Button
FreeThe primary interactive element for triggering actions. Comes in 5 types (Primary, Secondary, Tertiary, Danger, Warning), 3 sizes (SM, MD, LG), and 6 states (Default, Hover, Pressed, Focus, Disabled, Loading). Primary is for the most important action in a view; Secondary supports it; Tertiary is for low-emphasis actions.
90 variants
Variants
| Variant | Description | When to use |
|---|---|---|
| Primary | High-emphasis button with a solid brand-colour fill. Draws the most attention. | Use for the single most important action per view — "Save", "Submit", "Create". |
| Secondary | Medium-emphasis button with a subtle background or outline style. | Use alongside a Primary button for supporting actions — "Cancel", "Back". |
| Tertiary | Low-emphasis text button with no background or border at rest. | Use for minor actions that shouldn't compete for attention — "Learn more", "Skip". |
| Danger | Red-toned button that signals a destructive or irreversible action. | Use for delete, revoke, or permanently destructive operations. |
| Warning | Amber-toned button that signals caution without implying danger. | Use for actions that need user consideration but aren't destructive — "Override", "Reset". |
Usage Guidelines
Use Primary for the single most important action per view.
Place more than one Primary button in the same section.
Use Secondary for supporting actions alongside a Primary.
Use Danger styling for non-destructive actions.
Use Danger for destructive actions like delete or revoke.
Disable buttons without explaining why via a tooltip.
Use Warning for actions that need caution but aren't destructive.
Mix button sizes within the same action group.
Code
<button class="lex-button lex-button--primary lex-button--md">
Save changes
</button>
<button class="lex-button lex-button--secondary lex-button--md">
Cancel
</button>
<button class="lex-button lex-button--danger lex-button--sm">
Delete
</button>.lex-button--primary {
background: var(--lex-button-primary-bg);
color: var(--lex-button-primary-text);
border-radius: var(--lex-radius-md);
height: var(--lex-control-height-md);
padding: 0 var(--lex-space-16);
font-weight: 500;
font-size: var(--lex-font-size-sm);
border: none;
cursor: pointer;
transition: background 150ms ease;
}
.lex-button--primary:hover {
background: var(--lex-button-primary-bg-hover);
}
.lex-button--primary:active {
background: var(--lex-button-primary-bg-pressed);
}
.lex-button--primary:disabled {
background: var(--lex-button-primary-bg-disabled);
color: var(--lex-button-primary-text-disabled);
cursor: not-allowed;
}// Using Lexicon CSS classes with React
export function SaveForm() {
return (
<div style={{ display: 'flex', gap: 8 }}>
<button className="lex-button lex-button--primary lex-button--md">
Save changes
</button>
<button className="lex-button lex-button--secondary lex-button--md">
Cancel
</button>
</div>
);
}Design Tokens
| Token | Value (dark) | Value (light) | CSS property |
|---|---|---|---|
| --lex-btn-bg | — | — | bg |
| --lex-btn-text | — | — | text |
| --lex-btn-border | — | — | border |
| --lex-btn-radius | — | — | radius |
| --lex-btn-padding-x | — | — | x |
| --lex-btn-padding-y | — | — | y |
| --lex-btn-font-size | — | — | size |
| --lex-btn-font-weight | — | — | weight |
Accessibility
- Use native <button> element — never <div> or <span> with click handlers.
- Minimum touch target is 44×44px (WCAG 2.5.5 AAA).
- Disabled buttons should use aria-disabled="true" and include a tooltip explaining why.
- Focus ring uses the focus/ring token — 2px offset, brand colour.
- Button text must meet 4.5:1 contrast ratio against the background.