Button
Displays a button or a component that looks like a button.
When to Use
Use Button when you need to:
- Trigger an action like submit, save, delete, or navigate
- Provide a clear call-to-action in forms or dialogs
- Toggle visibility or state (open/close, expand/collapse)
- Initiate processes like uploads, downloads, or searches
- Create navigation that needs button styling (using asChild)
When Not to Use
- Inline text navigation - use a standard link or
variant="link" - Icon-only actions in toolbars - consider Icon Button for animated feedback
- Binary toggle states - use Toggle or Switch
- Grouped exclusive options - use Toggle Group
Default
The default appearance of the button component.
Sizes
Available size options: sm, default, lg, with matching icon variants (icon-sm, icon, icon-lg).
Variants
Different visual styles for various use cases and emphasis levels.
States
Interactive states including disabled and focus indicators.
Disabled
Focus
Tab to any button to see the focus ring. Focus styles include a ring with 3px width using the ring color from your theme.
Icon
Icon-only buttons for compact actions. Use size='icon' variants for square buttons.
With Icon
Buttons with leading or trailing icons. Spacing is automatically adjusted based on button size.
Rounded
Use the rounded-full class to create pill-shaped buttons.
Loading
Loading state with spinner icon. Combine disabled prop with Loader2 icon.
As Child
Use asChild prop to render buttons as links or other components while preserving button styles.
UX & Design Guidelines
Visual Hierarchy
Use variant="default" for primary actions (one per view), variant="secondary" or variant="outline" for secondary actions, and variant="ghost" for tertiary/low-emphasis actions. Reserve variant="destructive" for irreversible actions.
Spacing & Layout
When grouping buttons, use gap-2 for tight layouts or gap-4 for standard spacing. Place the primary action on the right in modal dialogs (following platform conventions). Use consistent sizing within a group.
Responsive Behavior
On mobile, consider using size="lg" for better touch targets (minimum 44×44px). Icon-only buttons should expand to include labels on larger screens when space permits. Full-width buttons (className="w-full") work well in narrow containers.
Color & Contrast
All button variants meet WCAG 2.1 AA contrast requirements. The primary variant uses bg-primary with text-primary-foreground for maximum contrast. Disabled states reduce opacity to 50% while maintaining readability.
Accessibility
Keyboard Navigation
- Tab — Move focus to/from the button
- Enter or Space — Activate the button
- When using
asChildwith links, Enter navigates (standard link behavior)
Screen Reader Support
- Buttons announce their text content and role automatically
- Icon-only buttons require
aria-labelfor screen reader users - Disabled state is announced via
disabledattribute - Use
aria-describedbyfor additional context on destructive actions
Focus Management
Visible focus ring with 3px width using focus-visible:ring-[3px]. Focus states meet WCAG 2.1 Level AA requirements. The ring color adapts to the button variant (destructive buttons use a red ring).
Touch Targets
Default size is 36px height (h-9), meeting minimum touch target recommendations. Use size="lg" (40px) for critical touch interactions. Icon buttons maintain square dimensions for consistent hit areas.
ARIA Attributes
{/* Standard button */}
<Button onClick={handleSubmit}>Submit Form</Button>
{/* Icon-only button - requires aria-label */}
<Button size="icon" aria-label="Search">
<Search className="size-4" />
</Button>
{/* Button that controls expanded state */}
<Button
aria-expanded={isOpen}
aria-controls="dropdown-menu"
onClick={toggleMenu}
>
Menu
</Button>
{/* Destructive action with confirmation context */}
<Button
variant="destructive"
aria-describedby="delete-warning"
>
Delete Account
</Button>
<span id="delete-warning" className="sr-only">
This action cannot be undone
</span>Related Components
API Reference
The Button component accepts the following props in addition to standard button attributes.
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "default" | "outline" | "ghost" | "destructive" | "secondary" | "link" | "default" | The visual style variant of the button. |
| size | "default" | "sm" | "lg" | "icon" | "icon-sm" | "icon-lg" | "default" | The size of the button. Icon sizes create square buttons. |
| asChild | boolean | false | When true, the button will render its child as the root element, merging props and behavior. |
| disabled | boolean | false | When true, prevents user interaction and applies disabled styles. |
| className | string | — | Additional CSS classes to apply to the button. |