Specify a component's anatomy, variants, states and behaviour so it can be built once and used everywhere.
Why it matters
A component that only exists as one pretty picture will be built differently by every developer who touches it. What happens on hover? What does it look like disabled, loading or with a very long label? Does it work with a keyboard? A component spec answers those questions once, so the component is built correctly, documented, and reused everywhere. Writing clear specs is one of the clearest signs of a mid-level designer.
The core idea: anatomy, variants, states, behaviour
A complete spec covers four things.
1. Anatomy. The named parts of the component. For a button: container, label, optional leading icon, optional trailing icon. Name parts the way developers will (match the code where possible).
2. Variants. Deliberate, designed differences that a designer chooses when placing the component:
- Type or emphasis: primary, secondary, tertiary (text-only), danger.
- Size: small, medium, large.
- Content options: with icon, icon-only.
3. States. Differences caused by interaction or system status, which every variant must handle:
| State | Trigger | Typical visual change |
|---|---|---|
| Default (rest) | Nothing happening | Base style |
| Hover | Pointer over it | Slightly darker background |
| Focus | Keyboard focus | Visible focus ring (at least 3:1 against the background) |
| Active (pressed) | Being pressed | Darker still, or slight inset |
| Disabled | Not available | Reduced emphasis; not focusable or explained |
| Loading | Action in progress | Spinner, label kept or changed to "Saving...", repeat clicks blocked |
Form inputs add more: filled, error, read-only, and help-text states. Remember that a state like focus must be visible on every variant, not just the primary one.
4. Behaviour and content rules. What happens and what is allowed: keyboard support (Enter and Space activate a button), long labels (wrap or truncate?), minimum target size (for example at least 24 by 24 CSS pixels under WCAG 2.2, and many teams use 44 or 48), icon-only buttons need an accessible name, and when to use each variant ("one primary button per view").
Variants in Figma
In Figma, a component set groups variants and uses properties to switch between them. A button might have:
Type= Primary, Secondary, Danger (variant property)Size= Small, Medium (variant property)State= Default, Hover, Focus, Pressed, Disabled, Loading (variant property)Label(text property) andShow icon(boolean property)
Three types x two sizes x six states = 36 variants. That sounds like a lot, but building them all is how you find gaps, such as a danger button whose focus ring is invisible against red. Build each variant with auto layout and tokens (variables), so changes flow through.
Worked example: a button spec
Component: Button
Anatomy: container | leading icon (optional) | label | trailing icon (optional)
Variants:
Type: primary (filled, color-primary), secondary (outline, color-primary border),
danger (filled, color-danger)
Size: medium (height 44, padding-x space-4, font-size-body)
small (height 32, padding-x space-3, font-size-small)
States (every type and size):
hover background -> *-hover token
focus 2px focus ring color-focus, 2px offset, visible on all types
pressed background -> *-active token
disabled 40% opacity is NOT used (fails contrast); use color-disabled-bg and
color-disabled-text, and prefer explaining why the action is unavailable
loading spinner replaces leading icon, label "Saving...", aria-busy, ignore repeat clicks
Behaviour:
Enter and Space activate. Label wraps to max 2 lines; never truncate.
Icon-only buttons require an accessible label (e.g. "Close").
Usage:
One primary button per view. Danger only for destructive, irreversible actions.
Notice the spec ties every visual decision to a token (previous lesson), covers every state for every variant, and states rules that a developer or a future designer can follow without asking you.
Where specs live
Specs live in the design file (a documentation page next to the component) and in the system's docs site. Many teams also document components in code with a tool such as Storybook, which shows each state live. Whatever the tool, design and code docs should say the same thing.
Common mistakes
- Only designing the default state. Developers then invent hover, focus and error.
- Confusing variants and states. A danger button is a variant; hovered is a state. Mixing them creates a tangled component set.
- Invisible focus on some variants.
- Disabled = low opacity text that nobody can read, with no explanation.
- Hard-coded values instead of tokens.
- No usage rules. Without "when to use", people use the danger style because they like red.
Quick recap
- A component spec covers anatomy, variants, states and behaviour, plus usage rules.
- Variants are designed choices (type, size); states come from interaction (hover, focus, pressed, disabled, loading).
- In Figma, build a component set with variant, text and boolean properties, using auto layout and variables.
- Every state must exist and be accessible on every variant.
Try it
On the Do tab you will write a full spec for a component, with every state for every variant.