The tangible win
After this lesson, you should be able to look at a component API and say whether something should be a variant, a state, a size, or a composition.
Why the distinction matters
Material Design lists button styles such as filled, tonal, outlined, elevated, and text (Material buttons). Carbon documents button kinds such as primary, secondary, tertiary, danger, and ghost (Carbon button usage).
Those are not random skins. They encode product intent: emphasis, hierarchy, risk, and context. A variant should help a product team choose the right action style without inventing a new visual treatment each time.
The four buckets
| Bucket | Question | Examples |
|---|---|---|
| Variant | What role or emphasis is intended? | Primary, secondary, danger, ghost. |
| State | What is happening right now? | Hover, focus, pressed, loading, disabled. |
| Size | What density or layout context is needed? | Small, medium, large, icon-only. |
| Composition | How does it combine with other elements? | Button group, toolbar, form footer. |
Backend analogy: avoid boolean soup
A weak component API looks like this:
<Button blue big disabled danger loading dashboard />
It mixes appearance, size, state, risk, and screen location. A stronger API separates concerns:
<Button
variant="danger"
size="md"
loading={isDeleting}
disabled={!canDelete}
>
Delete account
</Button>
Now the component has a readable product contract: this is a dangerous action, medium density, currently loading or disabled depending on data.
Practice: classify the prop
A designer asks for Button variant="loading". What should you say?
Variant smell tests
A proposed variant is suspicious if it is named after:
- A screen:
dashboardButton - A requester:
pmSpecial - A raw color:
blueButton - A vague feeling:
extraImportant
A healthier variant names a stable product decision: primary, secondary, danger, quiet, link.
Read next
Primary source: skim Material buttons and notice how button types map to emphasis. Then skim GOV.UK Button and notice their usage guidance for start, secondary, warning, and disabled buttons.
Ask me for examples if you want: we can design a clean Button API together or refactor a messy one.