Tags: web-dev ux concept

Component States

Date: 2026-08-16


The set of appearances a component can take, most of which get designed after launch when someone finds one missing. The list is knowable up front, and writing it down is the cheapest quality improvement available to a design system.


Component states are the distinct visual and behavioural conditions a component can be in — interaction states it enters from user input, and content states it enters from data.

Two different lists, both routinely incomplete.

Interaction states

default      resting
hover        pointer over it
focus        keyboard focus — MUST be visible
focus-visible  focus from keyboard, not mouse
active       being pressed
disabled     present, not operable
loading      operating, awaiting a result
selected     chosen, in a set

focus is the one that gets removed — usually by a global outline: none early in a project, and usually never replaced. It’s the only state with a hard accessibility requirement, because without it a keyboard user cannot tell where they are — Keyboard Navigation, WCAG.

:focus-visible is the right selector. It shows the indicator for keyboard focus and suppresses it for mouse clicks, which is what people were trying to achieve when they removed focus styling altogether.

Content states

The list that gets forgotten entirely, because the design was made with realistic data:

empty        no data yet
loading      fetching
partial      some data, more coming
error        the request failed
too much     200 items in a 5-item list
too long     a 90-character product name
too short    a one-character name
missing      no image, no description

Every one of these ships to production whether or not it was designed. Undesigned, they appear as a blank rectangle, a stretched layout, or a broken image icon.

DESIGNED FOR              WHAT SHIPS
"Blue Cotton Shirt"       "Professional
                           Anti-Ageing Serum
                           With Hyaluronic
                           Acid 50ml Twin Pack"
                           ↑ breaks the card

Disabled deserves its own argument

Disabled controls are worse than they look:

  • Low contrast by convention, so they often fail contrast requirements
  • Not focusable, so keyboard and screen-reader users may not know they exist
  • No explanation. A disabled button doesn’t say why, and the user can’t ask it

Prefer an enabled control that explains the problem to a disabled one that doesn’t. A submit button that stays active and reveals validation messages on click is more usable than one that greys out silently — Inclusive Design.

Combinations, which is where it gets real

States aren’t independent, and the matrix is bigger than the list:

              default  hover  focus  disabled
primary          ✓       ✓      ✓       ✓
secondary        ✓       ✓      ✓       ✓
danger           ✓       ✓      ✓       ✓
loading          ✓       –      ✓       –

Multiply by theme and by variant and a button has dozens of appearances. You do not design each one — you define how each state modifies the base, and the combinations follow. That’s what makes states a token problem rather than a design problem.

Making the list stick

  • Put every state in the component’s documentation page, rendered, not described — Component Documentation
  • Test with hostile content. The longest realistic string, the missing image, the empty array. A component that only works with tidy data is untested
  • Loading needs a shape. A spinner that replaces content causes layout shift; a skeleton matching the eventual dimensions doesn’t — Cumulative Layout Shift
  • Error states need a way out. “Something went wrong” with no retry is a dead end

The honest position

The set is always incomplete. Something will present a state nobody anticipated — a currency with four decimal places, a right-to-left language, a name in a script your font lacks.

The goal isn’t completeness; it’s that the known list is covered, so the surprises are genuinely surprising rather than the ones everyone could have predicted.