Website Markup Using Radix UI
Radix UI is a library of unstyled (headless) primitives for React with a focus on accessibility. It provides correct semantics, keyboard navigation, ARIA attributes, and focus management — without imposing visual styles. Developers write their own CSS/Tailwind.
Radix Principles
Unstyled: components carry no visual styles. <Dialog.Root> has no color or padding — only logic.
Accessible by default: every component implements WAI-ARIA patterns. For example, <Select> automatically manages role="combobox", aria-expanded, aria-activedescendant, keyboard navigation (arrows, Enter, Escape).
Composable: components consist of parts (Anatomy) that can each be styled independently.
Installation and Usage
npm install @radix-ui/react-dialog @radix-ui/react-select @radix-ui/react-dropdown-menu
import * as Dialog from '@radix-ui/react-dialog';
function Modal() {
return (
<Dialog.Root>
<Dialog.Trigger asChild>
<button className="btn-primary">Open</button>
</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Overlay className="fixed inset-0 bg-black/50 backdrop-blur-sm" />
<Dialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-white rounded-lg p-6 w-full max-w-md shadow-xl focus:outline-none">
<Dialog.Title className="text-xl font-semibold">Title</Dialog.Title>
<Dialog.Description className="mt-2 text-gray-600">
Dialog description.
</Dialog.Description>
<Dialog.Close asChild>
<button className="absolute top-4 right-4" aria-label="Close">
✕
</button>
</Dialog.Close>
</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>
);
}
Styling States Through Data Attributes
Radix sets data-state attributes that can be used in CSS:
/* Dialog appearance animation */
[data-state="open"] .dialog-overlay {
animation: fadeIn 150ms ease;
}
[data-state="closed"] .dialog-overlay {
animation: fadeOut 150ms ease;
}
/* Select open state */
[data-state="open"] .select-trigger {
border-color: #2563eb;
}
With Tailwind — via the tailwindcss-radix plugin:
<Select.Trigger className="data-[state=open]:border-blue-500 data-[placeholder]:text-gray-400" />
Accessibility — What You Get for Free
- Focus trap: in Dialog and Popover, focus automatically moves inside and doesn't escape
- Escape to close: Dialog, Popover, Select close on Escape
- Scroll lock: with Dialog open — page doesn't scroll
-
ARIA: automatic
aria-haspopup,aria-expanded,aria-controls,role - Keyboard nav: in Select, Menu, RadioGroup — arrows + Home/End
Radix Primitives Components
- Dialog, AlertDialog, Sheet
- Select, DropdownMenu, ContextMenu, NavigationMenu
- Tooltip, Popover, HoverCard
- Accordion, Tabs, Collapsible
- Checkbox, RadioGroup, Switch, Slider
- Progress, ScrollArea, Separator
- Avatar, AspectRatio
Shadcn/ui — Radix Wrapper
Shadcn/ui provides ready-styled components based on Radix + Tailwind. Unlike typical UI libraries — components are copied into the project (npx shadcn-ui add button), not imported as a dependency. Complete freedom to modify.
Timeline
Implementing a set of UI components (modal, dropdown, select, tabs, form) using Radix UI + custom styles: 3–5 days depending on quantity and component complexity.







