API
States
--<utility>--<state>: a value while the element is in that state.
Color and effects utilities take a state tier: --bg: var(--color-background); --bg--hover: var(--color-muted). A state beats a breakpoint on the same utility, and the states rank in a fixed order, highest first:
| State | Matches |
|---|---|
starting | the element's @starting-style; see starting |
disabled | :disabled, [aria-disabled="true"] |
active | :active |
focus-visible | :focus-visible |
focus-within | :focus-within |
hover | :hover, only where the device can hover |
checked | :checked, [aria-checked="true"] |
current | [aria-current] with any value but "false": the current page, step, or location |
open | [open], :popover-open, [aria-expanded="true"] |
stuck | the nearest sticky container is stuck; see stuck |
Two consequences:
- A tier needs a base.
--text--hover: redalone does nothing on a plain element; write the base first. The utilities that work tier-only (padding,--bg, opacity, the transforms, shadow and the ring utilities, and a handful of layout utilities with a natural default) are flagged in the utility tables;--bg--hover: var(--color-muted)alone paints a plain element on hover. Where a primitive sets the property itself, its value wins over a tier alone unless the primitive reads that utility (a button reads--bg, a popover does not). - A utility on a primitive flattens its states.
--bg: redon a button is red on hover too, because the utility outranks the button's own:hoverrule. To keep the primitive's behavior, set its state hook instead:--ui-button-bg--hover.