Skip to main content
Pricing

Icon Button

Free

A compact button displaying only an icon, with no visible text label. Comes in 4 types (Primary, Secondary, Tertiary, Danger), 3 sizes (SM, MD, LG), and 6 states (Default, Hover, Pressed, Focus, Disabled, Loading). Used for actions like close, menu toggle, settings, or copy — where the icon is universally understood. Always requires an accessible label via aria-label.

72 variants

Type
State
Size SM
Size MD
Size LG

Variants

VariantDescriptionWhen to use
PrimarySolid brand-colour fill icon button for high-emphasis actions.Use for key actions in toolbars or headers where space is limited.
SecondarySubtle background icon button for medium-emphasis actions.Use for secondary toolbar actions or inline controls.
TertiaryGhost icon button with no background at rest — appears on hover.Use for low-emphasis inline actions like edit or delete in lists.
DangerRed-toned icon button for destructive actions.Use for delete or remove actions in compact contexts.

Usage Guidelines

Do

Always provide aria-label describing the action — e.g., aria-label="Close dialog".

Don't

Use an Icon Button when a text label would be clearer for the action.

Do

Use universally recognised icons (✕ for close, ☰ for menu, ⚙ for settings).

Don't

Omit the aria-label — screen readers will announce nothing useful.

Do

Maintain 44×44px minimum touch target even if the visible icon is smaller.

Don't

Use decorative-only icons for interactive buttons.

Code

HTML
<button class="lex-icon-button lex-icon-button--secondary" aria-label="Close dialog">
  <svg width="20" height="20" viewBox="0 0 24 24" fill="none"
    stroke="currentColor" stroke-width="2">
    <line x1="18" y1="6" x2="6" y2="18" />
    <line x1="6" y1="6" x2="18" y2="18" />
  </svg>
</button>
CSS Custom Properties
.lex-icon-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--lex-icon-btn-size, 40px);
  height: var(--lex-icon-btn-size, 40px);
  border-radius: var(--lex-icon-btn-radius, var(--lex-radius-md));
  border: none;
  cursor: pointer;
  transition: background 150ms ease;
  color: var(--lex-icon-btn-color);
}

.lex-icon-button--secondary {
  background: var(--lex-icon-btn-bg);
}

.lex-icon-button--secondary:hover {
  background: var(--lex-icon-btn-bg-hover);
}
React
// Using Lexicon CSS classes with React
export function CloseButton({ onClose }: { onClose: () => void }) {
  return (
    <button
      className="lex-icon-button lex-icon-button--secondary"
      aria-label="Close dialog"
      onClick={onClose}
    >
      <svg width="20" height="20" viewBox="0 0 24 24" fill="none"
        stroke="currentColor" strokeWidth="2" strokeLinecap="round">
        <line x1="18" y1="6" x2="6" y2="18" />
        <line x1="6" y1="6" x2="18" y2="18" />
      </svg>
    </button>
  );
}

Design Tokens

TokenValue (dark)Value (light)CSS property
--lex-icon-btn-sizesize
--lex-icon-btn-radiusradius
--lex-icon-btn-bgbg
--lex-icon-btn-icon-sizesize

Accessibility

  • aria-label is required since there is no visible text content.
  • Ensure 44×44px minimum touch target on mobile, even when icon is smaller.
  • Use role="button" if not using a native <button> element.
  • Focus ring must be visible — use the same focus/ring token as Button.

Keyboard Interactions

EnterActivates the button.
SpaceActivates the button.
TabMoves focus to the next focusable element.