Icon button
An icon button runs an action with just an icon, like close, copy or more.
<IconButton label="More actions"><IconDots /></IconButton>When to use
Section titled “When to use”- For actions people know by their icon: close, back, copy, share, refresh, more.
- When space is tight and the same action repeats, like copy and explorer links on every address row.
When not to use
Section titled “When not to use”- If people would have to guess what the icon does, use a Button with a label.
- For the main action in a view, use a primary Button. Icon buttons are never primary.
- To pick one of a few options, even with icons, use a Segmented control.
- To turn a setting on or off, use a Switch.
Anatomy
Section titled “Anatomy”- 1ContainerA circle, 32 or 40px. Secondary has a fill and border; ghost has neither until hover.
- 2Icon20px on small, 24px on medium. Always a 1.67px line.
Variants
Section titled “Variants”- Secondary (the default) has a fill and a border. Use it when the button sits on its own, like a refresh button in a header.
- Ghost shows a fill only on hover. Use it in rows, dialog headers and groups, where many buttons sit close together.
The fills are the same as Button’s secondary and ghost. The icon rests at icon/secondary, a step quieter than a label, and turns icon/primary on hover, press and while its menu is open.
- Small (32px, 20px icon) fits cards and dialog headers. In dense rows, like copy and explorer actions beside an address, give the icon
className="size-4"for a 16px icon. - Medium (40px, 24px icon) is the default, for page headers and toolbars.
Icon buttons that sit side by side should be the same size and variant. Every icon draws the same 1.67px line at any size, matching Button.
IconButtonGroup keeps related actions together in one pill. Buttons inside it are small and ghost unless you set otherwise. Give the group a label. Each button is its own Tab stop.
States
Section titled “States”Try the playground to see hover, pressed and focus. A pressed icon button shrinks slightly, to 95%, unless the user has turned on reduced motion. That’s a little more than Button’s 97%, which is too small to feel at 32px.
When an action finishes in place, like copy, swap the icon to a check for a moment. Wrap the icons in IconSwap so the old one shrinks away and the new one grows in, and use DrawnCheck so the check strokes itself in. Neither animates on first render, and with reduced motion the swap is a plain fade.
<IconButton label="Copy token address" onClick={() => copy(address)}> <IconSwap swapKey={copied ? "check" : "copy"}> {copied ? <DrawnCheck className="text-positive" /> : <IconCopy />} </IconSwap></IconButton>Disabled
Section titled “Disabled”Disable an icon button only when you have to, and say why nearby. Hiding an action that never applies is often clearer.
Content
Section titled “Content”- The
labelnames the action, not the icon: Close dialog, not X. - Use sentence case and no full stop. Name the thing when it helps: Copy token address is clearer than Copy.
- Use Tabler icons at stroke 2, the same icon for the same action everywhere.
Behaviour
Section titled “Behaviour”| Key | Action |
|---|---|
| Tab | Moves focus to the icon button. |
| Enter or Space | Runs the action. |
With asChild and a link, Enter follows the link and Space doesn’t, as for any link.
Accessibility
Section titled “Accessibility”labelis required and becomes thearia-label. It’s the only name screen readers get.- The
labelalso shows in a Tooltip on hover and keyboard focus. Touch screens never show it, so still pick icons people already know. - For a button that toggles, like show and hide, set
aria-pressedor change thelabelwith the state, never both. - Keyboard focus shows the same 2px ring with a 2px gap as Button. Don’t remove it.
| Prop | Type | Default | Notes |
|---|---|---|---|
label |
string |
(required) | The accessible name. |
variant |
"secondary" | "ghost" |
"secondary" |
"ghost" inside an IconButtonGroup. |
size |
"sm" | "md" |
"md" |
"sm" inside an IconButtonGroup. |
asChild |
boolean |
false |
Gives the child, usually a link, the icon button’s styles. |
tooltip |
boolean |
true |
Shows the label in a Tooltip. Turn off when the same words sit beside the button. |
tooltipSide |
"top" | "right" | "bottom" | "left" |
"top" |
Where the tooltip opens. |
Every other <button> prop passes through, including disabled, onClick and aria-pressed. IconButtonGroup takes a required label and passes other props to its <div>.
Related
Section titled “Related”- A Button runs an action with a label, with or without an icon.
- A Segmented control picks one of a few options.