IconButton
IconButton is a square button that displays only an icon. Used in toolbars, navigation, and compact UIs.
6
Variants
5
Sizes
1:1
Aspect Ratio
Pure
React
Playground
Preview
solidD40px / Icon 20px
Variant
Color
Size
Radius
Icon
State
<IconButton aria-label="Action">
<Search />
</IconButton>Variants
Style
Solid
Solid fill — the most visually prominent option
Add, Submit
Outline
Neutral — blends with the background
Info, Details
Ghost
Minimal — no background fill, ideal for toolbars
Toolbar
Subtle
Subtle — revealed on hover, great for headers and nav
Header, Nav
Solid Colors
Default
Dark — the most versatile CTA
Add, Submit
Primary
Brand color — for brand-emphasis actions
Favorite
Secondary
Supplementary — pairs with a primary action
Settings, Edit
Destructive
Destructive — for deletes and irreversible actions
Delete, Close
Sizes
xsSize28px
Icon14px
smSize32px
Icon16px
mdSize36px
Icon16px
defaultSize40px
Icon20px
lgSize48px
Icon24px
| Size | Width | Height | Icon | Preview |
|---|---|---|---|---|
xs | 28px | 28px | 14px | |
sm | 32px | 32px | 16px | |
md | 36px | 36px | 16px | |
default | 40px | 40px | 20px | |
lg | 48px | 48px | 24px |
Touch target: WCAG 2.5.8 requires a minimum 24px touch area. Even the smallest xs (28px) meets the WCAG standard.
States
Solid Primary
Outline
Subtle
// Solid primary states
<IconButton color="primary" aria-label="Default"><Pencil /></IconButton>
<IconButton color="primary" loading aria-label="Loading"><Pencil /></IconButton>
<IconButton color="primary" disabled aria-label="Disabled"><Pencil /></IconButton>
// Outline states
<IconButton variant="outline" aria-label="Default"><Pencil /></IconButton>
<IconButton variant="outline" loading aria-label="Loading"><Pencil /></IconButton>
<IconButton variant="outline" disabled aria-label="Disabled"><Pencil /></IconButton>
// Subtle states
<IconButton variant="subtle" aria-label="Default"><Pencil /></IconButton>
<IconButton variant="subtle" loading aria-label="Loading"><Pencil /></IconButton>
<IconButton variant="subtle" disabled aria-label="Disabled"><Pencil /></IconButton>API
Props
variant"solid""solid" | "outline" | "ghost" | "subtle"Button style
color"default""default" | "primary" | "secondary" | "destructive"Color for solid variant. Ignored for non-solid
size"default""xs" | "sm" | "md" | "default" | "lg"Button size (28/32/36/40/48px)
radius"default""none" | "sm" | "base" | "default" | "lg" | "xl" | "2xl" | "3xl" | "full"Border radius size (6px)
loadingfalsebooleanLoading state
disabledfalsebooleanDisabled state
pressEffectundefinedbooleanPress effect (active:scale-pressed). Defaults to true. Set false to disable
asChildfalsebooleanRender as Slot
aria-labelundefinedstringAccessibility label (required)
| Name | Type | Default | Description |
|---|---|---|---|
variant | "solid" | "outline" | "ghost" | "subtle" | "solid" | Button style |
color | "default" | "primary" | "secondary" | "destructive" | "default" | Color for solid variant. Ignored for non-solid |
size | "xs" | "sm" | "md" | "default" | "lg" | "default" | Button size (28/32/36/40/48px) |
radius | "none" | "sm" | "base" | "default" | "lg" | "xl" | "2xl" | "3xl" | "full" | "default" | Border radius size (6px) |
loading | boolean | false | Loading state |
disabled | boolean | false | Disabled state |
pressEffect | boolean | undefined | Press effect (active:scale-pressed). Defaults to true. Set false to disable |
asChild | boolean | false | Render as Slot |
aria-label | string | undefined | Accessibility label (required) |
Anatomy
1
2
Container (default)
40px × 40pxIcon (default)
20px (icon-md)1
Container
Square (1:1) · border-radius
2
Icon
Center-aligned · required
Best Practices
✓
Recommended
- ✓Always set aria-label
- ✓Use icons with clear meaning
- ✓Use together with tooltips
- ✓Use 48px+ on mobile
✕
Avoid
- ✗Don't use without aria-label
- ✗Don't use ambiguous icons alone
- ✗Don't overuse instead of text buttons
- ✗Don't use sizes that are too small
Accessibility
Keyboard
TabMove focus
EnterActivate button
SpaceActivate button
WCAG 2.2 Compliance
- Contrast ratio 4.5:1 or higher
- Focus indicator
- aria-label support (required)
- aria-busy (auto-applied during loading)