The @wordpress/ui Button component does not provide visual feedback specific to the pressed state. :hover, :active, and :focus all share the same styles, so clicking a button looks the same as hovering it. There is no clear “pressed” moment before the click completes.
Current behavior
In packages/ui/src/button/style.module.css, interactive states are grouped:
&:not([data-disabled]):is(:hover, :active, :focus) {
background-color: var(--wp-ui-button-background-color-active);
color: var(--wp-ui-button-foreground-color-active);
border-color: var(--wp-ui-button-border-color-active);
}
The -active custom properties map to design tokens whose descriptions also combine hover, focus, and pressed (e.g. --wpds-color-bg-interactive-brand-strong-active: “hovered, focused, or active”). So the component and tokens treat “active” as one state, not a separate pressed state.
In Storybook, click and hold a button: it should look different from hover alone, but today it does not.
Why this matters
- Buttons should respond at the moment of interaction, not only on hover. Without distinct
:active styling, clicks can feel unresponsive, especially on touch devices where hover is absent and press is the main cue.
- Hover is exploratory (“what happens if I click?”). Press is commitment (“I am clicking now”). Using the same styles for both removes an important layer of feedback and makes the UI feel flat.
- The legacy
Button in @wordpress/components does distinguish :active from :hover — for example, primary buttons use a darker background on press ($components-color-accent-darker-20) than on hover ($components-color-accent-darker-10). As @wordpress/ui replaces @wordpress/components, we risk regressing a behavior users already expect.
- Gutenberg relies heavily on buttons in toolbars, inspectors, and dialogs. In those contexts, subtle but reliable press feedback helps users trust that their action registered. Especially for icon-only and compact buttons where color change alone may be hard to notice.
- The token docs define an
active state as “hovered, pressed, or selected.” That works for token naming, but components still need to decide how to map CSS pseudo-classes. Button currently collapses them entirely; we should decide intentionally whether pressed needs its own token(s), or some other treatment.
Possible directions
- Add new color tokens and mimic
Button in @wordpress/components.
- If we do this we should ensure all button variants include
:active styles that differ from hover and focus.
- A non-color based approach, e.g. a subtle scale animation.
- Something else?
The
@wordpress/uiButtoncomponent does not provide visual feedback specific to the pressed state.:hover,:active, and:focusall share the same styles, so clicking a button looks the same as hovering it. There is no clear “pressed” moment before the click completes.Current behavior
In
packages/ui/src/button/style.module.css, interactive states are grouped:The
-activecustom properties map to design tokens whose descriptions also combine hover, focus, and pressed (e.g.--wpds-color-bg-interactive-brand-strong-active: “hovered, focused, or active”). So the component and tokens treat “active” as one state, not a separate pressed state.In Storybook, click and hold a button: it should look different from hover alone, but today it does not.
Why this matters
:activestyling, clicks can feel unresponsive, especially on touch devices where hover is absent and press is the main cue.Buttonin@wordpress/componentsdoes distinguish:activefrom:hover— for example, primary buttons use a darker background on press ($components-color-accent-darker-20) than on hover ($components-color-accent-darker-10). As@wordpress/uireplaces@wordpress/components, we risk regressing a behavior users already expect.activestate as “hovered, pressed, or selected.” That works for token naming, but components still need to decide how to map CSS pseudo-classes.Buttoncurrently collapses them entirely; we should decide intentionally whether pressed needs its own token(s), or some other treatment.Possible directions
Buttonin@wordpress/components.:activestyles that differ from hover and focus.