What it is
A control that performs an action in place: submitting, confirming, opening, applying, deleting. Its visual weight declares how much the interface wants you to press it. This page covers the whole button concept — with a label, with a label and an icon, with an icon alone, and the filter control. They are one thing to a reader and several exports in the package; the mapping is below.Live example
Exports
One page, three exports. A designer can read the page as one component; an engineer needs to know which to import.ButtonGroup is documented separately — see
Button group. It governs the relationship between
buttons rather than a button itself, which is a different decision.This grouping is a documentation choice, not a code change. Why the two structures differ
is recorded in TITAN-DIV-10.Vocabulary
The design team names buttons by prominence — how much the interface wants this pressed. That is the system’s vocabulary, it matches the naming specification’sprominence axis, and it
is a variant property of the design library’s own Button component with exactly these three
values. It is not a habit of speech; it is built into the library.
Say primary, secondary, tertiary. They describe the decision — relative weight — rather
than the treatment that happens to express it. A borderless button is still tertiary if the
weight is what you meant.
tertiary is specified and never implemented. The naming specification lists it on the
prominence axis, and no shipped token carries the word — the treatment exists in code only
as variant="text". See TITAN-DIV-11.Choose Button when
- The control performs an action rather than retrieving a resource — submit, confirm, apply, delete, open a dialog.
- The result of pressing it is a change in application state.
- The user would not reasonably want to open the result in a new tab.
Choose something else when
Button vs. Link is the fork people get wrong most often. The test is not appearance — a
Link can be styled to look like a button. The test is the result: does pressing it change
state (Button), or does it take me to a resource that has a URL (Link)? If a URL exists, it
must be reachable by right-click.
Anatomy
For an icon-only button the icon is the label, which is why it needs an accessible name
supplied separately — see Accessibility.
Variants
Prominence encodes how much the interface wants this pressed, not how severe the consequence is. A destructive action is frequently the tertiary control on the screen.Border adds to the box. The three levels carry different border widths, so they do not
share internal geometry even at the same size. A row mixing them will not align on the label
baseline by default.
The axes a Button actually has
Five, and naming them is what keeps a review from arguing about two different things at once. These are the design library’s own variant properties, and each maps to something in code:
Two combinations the design library does not publish:
- A trailing icon. The
Typeaxis has a leading icon and no trailing one. - An icon-only button below primary prominence. Icon-only exists at primary, default purpose, and nowhere else.
What Storybook publishes
Edge and failure states
The state everyone designs is a short label on a wide button. These are the others.Tokens
Composition
Action group order — trailing-primary. The primary action sits last (rightmost in LTR), with dismissive actions to its left.- The primary button is last.
- Dismissive actions (
Cancel,Close) are first, always tertiary. - Group separation uses a spacing token on the container, never a margin on the button.
Content
Title case here means headline style, not “every word capitalized.” Lowercase short
articles, conjunctions, and prepositions (
a, the, to, of, and) unless one is the
first or last word — “Save Changes to Draft,” not “Save Changes To Draft.” The theme’s
rendering doesn’t know this exception on every label — see
Open issues for where that bites.Delete Campaign is self-describing at the moment of commitment.
Accessibility
- Renders a native
<button>. Never applyrole="button"to adiv. - The accessible name comes from
children. An icon-only button has no text, so it requires an explicit accessible name — without one it is announced as “button” and nothing else. loadingsetsaria-busy="true"and disables the control.- Label contrast meets WCAG 2.2 AA (4.5:1). A tertiary button on a tinted surface is the historical failure case — verify it against the surface it actually sits on, not white.
Constraints
Retired
Known issues
Button: open issues
Divergences, open decisions, and undocumented gaps for Button.
Why it works this way
Labels are one line, by construction. A row of buttons reads as a row because the controls share a baseline and a height. Allowing one label to wrap trades that for the ability to write a longer label — and the longer label was the thing to fix. The theme holds the line so the decision does not depend on every author noticing it. Prominence is decoupled from severity. The most common request is to make destructive actions red and prominent so users “can’t miss them.” Prominence is an invitation. The interface should be easy to escape and deliberate to commit — so the destructive action takes a lower prominence and the escape route gets the weight. Severity is carried by the colour intent, the copy, and the confirmation step, never by prominence. The vocabulary is prominence, not treatment. “Primary” names the decision — this is the action the view exists to enable. “Contained” names one way of drawing it. Naming the decision means the rule survives a visual change: if primary buttons stopped being filled tomorrow, TITAN-BTN-01 would still say the right thing. Trailing-primary ordering matches the platform conventions users bring from elsewhere, and puts the primary action nearest the pointer’s resting position for the action taken most often. Two sizes, not three. A third size is another definition to maintain, another row in every matrix, and another decision at every call site. Two covers dense contexts and standard ones. If a case for a third emerges it gets added to the token source — not by passing an un-themed value through. One page for several exports. Someone deciding between a labelled button and an icon-only one is making a single decision about emphasis and space. Splitting that across two pages makes them read one, decide, and never learn the alternative existed.Status
Related
- Button group — binding several buttons into one control
- Link — when the result has a URL
- Menu — when there are three or more actions
- Destructive confirmation — the pattern that governs delete flows
- Color · Space — the tokens behind the variants