Buttons
These guidelines define how buttons should look, behave, and be implemented across all products. The goal is to ensure a consistent, accessible, and intuitive user experience while maintaining flexibility and scalability.
✅ TL;DR​
- Use the correct variant for every button
- Only one primary button per page
- Destructive buttons always open a confirmation
- Use spacing and corner radius consistently
- Icon buttons must be circular and have labels
- Don’t use links for actions or buttons for navigation
- Avoid visual overload – use menus for secondary actions
🧩 Button Variants​
Use semantic variants based on the button’s purpose, not its appearance.
Semantic variants define the function of a button in the context of the UI, such as the ones below. Not all the following variants are needed in all applications.
Colors / Severity​
Variant | Use Case | Typical Colors | Notes |
---|---|---|---|
Primary | Main action on a page (e.g., “Save”, “Submit”) | Brand color background, white text | - One per page or screen - High contrast and visibility - Never used for destructive actions |
Secondary | Secondary action (e.g., “Cancel”, “Back”) | Neutral background or border | - Visual fallback to primary - Useful for “Back” or “Cancel” - Should not compete visually with primary |
Destructive / Danger | Dangerous or irreversible actions (e.g., “Delete”) | Red background or border | - Always trigger a confirmation overlay or modal before the action is executed - Be clearly labeled (“Delete”, not “Confirm”), not “OK” - Must never be the primary button unless it’s the only available action |
Success | Successful Actions (e.g., "Confirm") | Green background or border | - Signals that an action will positively confirm or resolve something (e.g., “Mark as Done”) - Used after success feedback (e.g., “Continue” after a successful form) |
Disabled | Non-interactive, inactive state of any variant | Muted text, subdued background or border | - Be visually muted (e.g., gray background, 50–70% opacity) - Tooltip or hint text should explain why the button is disabled - Use aria-disabled="true" or disabled attribute- Have no hover/focus/active interaction - Not be clickable or keyboard-focusable - Never hide disabled buttons — they should show users which actions are currently unavailable. |
Additional Button Variants
These buttons are often only used in edge cases. This list is not complete. You may want to have more/other variants.
Variant | Use Case | Typical Colors | Notes |
---|---|---|---|
Tertiary | Less important or contextual actions | Text-only, no background | - Very low priority - Perfect for “Show more”, “Edit” - Works well inline with text or in lists |
Accent | Emphasized but not primary (e.g., “Upgrade”, “Info”) | Custom accent color | - Used to draw attention to helpful but non-essential features (e.g., upsells) - Should feel optional, not mandatory |
Info | For actions that guide the user without commitment (e.g., "Done") | Blue/gray tone or primary color, icon optional | - Used for helpful or guiding interactions (e.g., “Why?”, “Learn more”) - Can contain icons - Should never block user flow or be required to continue |
White / Transparent | Use on dark backgrounds (e.g., hero banners, modals) | White text, transparent or subtle border | - Only for dark surfaces (e.g., hero sections, dark modals) - Text must be white and high contrast - Should have hover/focus states to ensure accessibility |
Use semantic color tokens like color.button.primary.bg
or color.button.destructive.hover
. See Color Guidelines
States​
State | What to Use |
---|---|
Default | Use the token for the current variant |
Hover | Slightly darker/lighter than base |
Active | Higher contrast or inset shadow |
Focus | Always show a visible focus ring (e.g., 1-2px outline) |
Disabled | Muted background, cursor not-allowed, no interaction |
🚦 Button Limits & Hierarchy​
To maintain clarity:
Rule | Recommendation |
---|---|
Max visible buttons per section | 3–4 |
Max primary button per page | 1 |
Max secondary buttons | 2-3 |
Max destructive buttons | 1, always ask for confirmation |
Use overflow or menus if… | >3 actions or low-priority options |
Avoid overwhelming users. Use dropdowns, kebab menus (⋮), or “More…” links for less-used actions.
⚙️ Possible Button Properties​
Your button component could potentially include the following props to ensure complete flexibility:
Prop | Type | Description |
---|---|---|
variant | string/enum (filled, outlined) | Defines the button color |
severity | string/enum (primary, secondary, tertiary, destructive) | Defines the button color |
size | string (sm, md, lg) | Controls padding and font size |
label | string | Button label/text |
icon | JSX/Icon component | Optional icon |
iconPosition | start | end | Icon placement |
disabled | boolean | Disables the button |
onClick | function | Click handler |
aria-label | string | For accessibility (especially for icon-only) |
fullWidth | boolean | Button stretches to parent width |
loading | boolean | Shows loading indicator and disables interaction |
🔗 Link Guidelines​
Rule | Recommendation |
---|---|
Appearance | Blue text, underlined by default |
Hover | Darker blue or underline (if not always shown) |
In buttons? | Only if styled as tertiary buttons |
Navigation links | Use semantic <a> tags, never fake links via <button> |
Non-nav actions | Use buttons, not links (e.g., “Submit”, “Retry”) |
Links that look like buttons confuse users and hurt accessibility. Use one visual language per function. If you still need a button to redirect, please use the redirect icon: