States
Overview
States tell people how an element reacts and what it currently is. They are expressed with overlays of different opacity, focus rings, colors, font weights or the opacity of the element — depending on the state and on the color below it.
The ending of a name tells the kind of state: -ing states are transitional and last only during the interaction (hovering, focusing, pressing, dragging); -ed states are static and stay after it (selected, activated, disabled).
| State | Kind | Set by |
|---|---|---|
| Resting | Default | — |
| Hovering | Transitional | The pointer, only on devices that can hover |
| Focusing | Transitional | The keyboard focus |
| Pressing | Transitional | Mouse button or finger down |
| Dragging | Transitional | Drag and drop |
| Selected | Static, public | A choice of the user, e.g. in a dropdown |
| Activated | Static, public | The current destination, e.g. the active menu item |
| Disabled | Static, public | The application, when an element can’t be used |
| Loading | Static, public | The application, while an action runs |
Try it
Hover, focus with the Tab key, press and toggle these components.
Combinations
States combine: an element can be selected, hovered and pressed at the same time, and shows all of it at once. The static states (rows) get their overlay first, the interactions (columns) lay theirs on top. Disabled elements don’t react at all.
The checkerboard behind the tiles shows where states change the opacity of the element.
Hover & focus overlays
Hover and focus lay an overlay of the current text color over the element. On surfaces the default strength is enough; colored elements like primary buttons, checkboxes and switches need a stronger overlay, which makes them lighter. Form elements may show a 1px primary border instead.
Focus ring
The keyboard focus gets a focus ring, always in primary — also for neutral elements — unless the element itself is primary, then it uses its own color. Form fields use a focus outline in a light shade together with a 1px border in the state color. The ring only shows for keyboard focus (:focus-visible), not after a click.
Focus can also add an overlay. When an element is focused and hovered at the same time, the focus overlay is used.
Pressed & dragging
Pressing scales the element down slightly and lowers its opacity, so it reacts right under the finger. Dragged elements are lifted to elevation 2.
Selected & activated
Selected communicates a choice of the user, e.g. in a dropdown or a table row. Activated highlights the current destination, chosen by the user or by default, e.g. the menu item of the current page. Both use a 6% primary overlay; activated also colors the text primary (see the combinations above). Navigation items may use text color and font weight instead, as long as the difference is clear.
Disabled & loading
Disabled elements can’t be interacted with in any way. They get a neutral-300 background with neutral-400 text, or 35% opacity with pointer-events: none — the latter suits form elements and contextual information like “No results”.
Loading elements keep their size and show a spinner instead of their content, e.g. buttons while their action runs. They ignore further clicks.
Using states
The state mixin of fusion-css renders the overlays of any combination of states. Use hover instead of :hover, it only applies on devices that can hover.
@use "@brynlabs/fusion-css/index" as fusioncss;.item {@include fusioncss.state(());@include fusioncss.hover {@include fusioncss.state(("hover": true));}@include fusioncss.focus-behavior {@include fusioncss.focus-ring;}&.selected {@include fusioncss.state(("selected": true));}&:active {@include fusioncss.state(("pressed": true));}}
| Opacity token | Value |
|---|---|
--opacity--state-hover | 4% |
--opacity--state-hover-strong | 8% |
--opacity--state-hover-extra-strong | 12% |
--opacity--state-focus | 8% |
--opacity--state-focus-strong | 12% |
--opacity--state-focus-extra-strong | 24% |
--opacity--state-selected | 6% |
--opacity--state-activated | 6% |

