ButtonGroup
ButtonGroup is a container component that visually groups related buttons. Used for toolbars, filters, action groups, and presenting multiple choices as a single unit.
Specify variant and size on ButtonGroup, and they auto-inherit to child Button/IconButtons. Individual overrides are also possible.
Playground
<ButtonGroup variant="outline">
<Button>Copy</Button>
<Button>Cut</Button>
<Button>Paste</Button>
</ButtonGroup>Variants
Sizes
ButtonGroup inherits Button size via Context. Same size rules as Button apply.
xssmmddefaultlg| Size | Height | H-Padding | Gap | Icon | Font | Preview |
|---|---|---|---|---|---|---|
xs | 28px | 10px | 4px | 14px | 12px | |
sm | 32px | 12px | 8px | 14px | 13px | |
md | 36px | 14px | 8px | 16px | 14px | |
default | 40px | 16px | 8px | 16px | 14px | |
lg | 48px | 24px | 8px | 16px | 16px |
Touch target: WCAG 2.5.8 requires a minimum 24px touch area. Even the smallest xs (28px) meets the WCAG standard.
Features
Variant Combinations
// Edit Actions (outline) - Click to execute immediately
<ButtonGroup variant="outline" size="sm">
<Button leftIcon={<Copy />}>Copy</Button>
<Button leftIcon={<Scissors />}>Cut</Button>
<Button leftIcon={<Clipboard />}>Paste</Button>
</ButtonGroup>
// Undo/Redo Actions (outline) - History operations
<ButtonGroup variant="outline" size="sm">
<IconButton aria-label="Undo"><Undo /></IconButton>
<IconButton aria-label="Redo"><Redo /></IconButton>
</ButtonGroup>
// Zoom Controls (outline) - Zoom in/out actions
<ButtonGroup variant="outline" size="sm">
<IconButton aria-label="Zoom out"><ZoomOut /></IconButton>
<IconButton aria-label="Reset"><RotateCcw /></IconButton>
<IconButton aria-label="Zoom in"><ZoomIn /></IconButton>
</ButtonGroup>
Orientation
API
Props
variantundefined"outline" | "ghost"Child Button variant (inherited via Context)
sizeundefined"xs" | "sm" | "md" | "default" | "lg"Child Button size (inherited via Context)
radiusundefined"none" | "sm" | "base" | "default" | "lg" | "xl" | "2xl" | "3xl" | "full"Child Button border radius (inherited via Context)
fontWeightundefined"normal" | "semibold"Child Button font weight (inherited via Context)
disabledundefinedbooleanDisable all buttons (inherited via Context)
orientation"horizontal""horizontal" | "vertical"Button layout direction
attachedtruebooleanWhether to visually join buttons together
| Name | Type | Default | Description |
|---|---|---|---|
variant | "outline" | "ghost" | undefined | Child Button variant (inherited via Context) |
size | "xs" | "sm" | "md" | "default" | "lg" | undefined | Child Button size (inherited via Context) |
radius | "none" | "sm" | "base" | "default" | "lg" | "xl" | "2xl" | "3xl" | "full" | undefined | Child Button border radius (inherited via Context) |
fontWeight | "normal" | "semibold" | undefined | Child Button font weight (inherited via Context) |
disabled | boolean | undefined | Disable all buttons (inherited via Context) |
orientation | "horizontal" | "vertical" | "horizontal" | Button layout direction |
attached | boolean | true | Whether to visually join buttons together |
Customization
All buttons use default values based on the design system spacing rules. Use the group's className to batch-customize all buttons.
Change Horizontal Padding
className="[&>button]:px-10"Equalize Button Width
className="inline-grid grid-flow-col auto-cols-fr"Tip:Default values are designed to maintain component consistency. Use customization when needed for UI implementation.
Anatomy
horizontal · verticalgroupBest Practices
Recommended
- ✓Only group related actions
- ✓Specify variant/size on ButtonGroup (inherits to children)
- ✓Aim for 3-5 buttons
- ✓Set aria-label for icon-only groups
<ButtonGroup variant="outline" size="sm">
<Button>A</Button>
<Button>B</Button>
</ButtonGroup>Avoid
- ✗Don't mix different sized buttons
- ✗Don't group unrelated actions
- ✗Don't cram 6+ buttons
- ✗Don't mix destructive buttons with others
Accessibility
Keyboard
ARIA Attributes
- role="group" auto-applied
- Semantic grouping
- aria-label recommended
- Focus visibility support
ButtonGroup vs ToggleGroup
They look similar but differ in purpose and behavior. Choose the appropriate component.
Purpose
ButtonGroup: Grouping action buttons
ToggleGroup: On/off state management
State management
ButtonGroup: Manual (selected prop)
ToggleGroup: Auto (Radix managed)
Selection mode
ButtonGroup: Manual control only
ToggleGroup: single / multiple
Value management
ButtonGroup: None
ToggleGroup: value / onValueChange
Use case
ButtonGroup: Toolbar, Action groups
ToggleGroup: Text alignment, Format
| Feature | ButtonGroup | ToggleGroup |
|---|---|---|
| Purpose | Grouping action buttons | On/off state management |
| State management | Manual (selected prop) | Auto (Radix managed) |
| Selection mode | Manual control only | single / multiple |
| Value management | None | value / onValueChange |
| Use case | Toolbar, Action groups | Text alignment, Format |
Selection guide: Use ToggleGroup when you want automatic state management. Use ButtonGroup when clicking triggers a specific action (API calls, etc.).