Skip to main content

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.

Note:

In applications that use TUM AET UI, use its Button component: it implements these variants, states, and sizes.


✅ 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 an accessible name (aria-label) and a tooltip
  • Targets are at least 24 Ă— 24 px, better 44 Ă— 44 px on touch devices
  • 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​

VariantUse CaseTypical ColorsNotes
PrimaryMain 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
SecondarySecondary 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 / DangerDangerous 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” or “OK”)
- Must never be the primary button unless it’s the only available action
SuccessSuccessful 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)
DisabledNon-interactive, inactive state of any variantMuted text, subdued background or border- Be visually muted (e.g., gray background, 50–70% opacity)
- Explain why the button is disabled, ideally with visible hint text
- Use the disabled attribute: the button is then neither clickable nor keyboard-focusable
- If users must be able to focus it (e.g., to read a tooltip with the reason), use aria-disabled="true" instead and ignore clicks in the handler
- Have no hover/active interaction
- 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.

VariantUse CaseTypical ColorsNotes
TertiaryLess important or contextual actionsText-only, no background- Very low priority
- Perfect for “Show more”, “Edit”
- Works well inline with text or in lists
AccentEmphasized 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
InfoFor 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 / TransparentUse 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
Tip:

Use semantic color tokens like color.button.primary.bg or color.button.destructive.hover. See Color Guidelines

States​

StateWhat to Use
DefaultUse the token for the current variant
HoverSlightly darker/lighter than base
ActiveHigher contrast or inset shadow
FocusAlways show a visible focus ring for keyboard users (:focus-visible), e.g., a 2px outline with at least 3:1 contrast to the surrounding colors
DisabledMuted background, cursor not-allowed, no interaction

🚦 Button Limits & Hierarchy​

To maintain clarity:

RuleRecommendation
Max visible buttons per section3–4
Max primary button per page1
Max secondary buttons2-3
Max destructive buttons1, always ask for confirmation
Use overflow or menus if…>3 actions or low-priority options
Caution:

Avoid overwhelming users. Use dropdowns, kebab menus (⋮), or “More…” links for less-used actions.


📏 Size & Target Area​

RuleRecommendation
Minimum target size24 Ă— 24 CSS px for every clickable area (WCAG 2.2, 2.5.8, Level AA), including icon buttons
Smaller targetsOnly if a 24 px circle centered on each small target overlaps neither another target nor the circle of another small target, so leave enough space between them
Touch / primary actionsPrefer 44 Ă— 44 CSS px (WCAG 2.5.5, Level AAA), especially on mobile
Visual vs. clickable sizeThe clickable area may be larger than the visible button (e.g., padding around an icon), but never smaller

⚙️ Possible Button Properties​

Your button component could potentially include the following props to ensure complete flexibility:

PropTypeDescription
variantstring/enum (filled, outlined, text)Defines the button style
severitystring/enum (primary, secondary, tertiary, destructive)Defines the button color
sizestring (sm, md, lg)Controls padding and font size
labelstringButton label/text
typebutton | submit | resetNative button type; default to button so that buttons inside forms don’t submit them by accident
iconJSX/Icon componentOptional icon
iconPositionstart | endIcon placement
disabledbooleanDisables the button
onClickfunctionClick handler
aria-labelstringFor accessibility (especially for icon-only)
fullWidthbooleanButton stretches to parent width
loadingbooleanShows loading indicator and disables interaction

RuleRecommendation
AppearanceBlue text, underlined by default
HoverDarker blue or underline (if not always shown)
In buttons?Only if styled as tertiary buttons
Navigation linksUse semantic <a> tags, never fake links via <button>
Non-nav actionsUse buttons, not links (e.g., “Submit”, “Retry”)
Note:

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: