Anticode Open builder

The opacity hover check: why fading on hover is weak feedback

The opacity hover check reads a page's stylesheet and fails it when a hover rule sets opacity. Fading a button or link when the pointer arrives is the quickest hover state to write, which is why so many generated sites use it, but it's also one of the least informative: the element gets fainter at the moment it should look most ready to press.

Updated · By the Anticode team

What a hover state is for

A hover state answers one question for someone using a mouse or trackpad: “if I click now, will something happen, and to what?” It confirms that the thing under the pointer is interactive and marks exactly where it begins and ends. That's useful on a busy card grid, in a navigation bar where links sit close together, or on a pricing table with several buttons.

Lowering opacity answers that question poorly. The element loses contrast against its background, so text on a faded button can drop below a comfortable reading level just as the visitor is about to act on it. On a pale background a small fade is easy to miss altogether. And because the change is a dimming rather than a shift, it can read as “disabled” rather than “ready”.

What the check matches

The Critic reads the CSS inside the page's style element and looks for any rule whose selector ends in :hover and whose declarations include opacity. A single match fails the check across the page. Some details of the rule matter:

  • Any opacity in a hover rule counts. A rule that changes the background and also sets opacity still fails. The label says the hover shouldn't just fade, but the test is stricter than the label: opacity anywhere in the rule is enough.
  • The selector has to end in :hover. .btn:hover is read. A rule such as .card:hover img, which styles a child when its parent is hovered, isn't matched by this check.
  • Only the stylesheet. Inline style attributes aren't part of this check, and nor is anything set from script.

Hover states that tell people more

A good hover state makes the element look more present, not less. Pick one change that suits the design and keep it consistent across the site:

Alternatives to an opacity fade
ElementA clearer hoverWhy it works
Filled buttonSlightly brighter or darker fillContrast holds, and the button reads as live
Outline buttonFill with the action colour, text in the contrasting colourA strong, unambiguous change of state
Text linkChange colour, or thicken or add the underlineMarks the exact extent of the link
Navigation itemMuted text becomes full-strength textThe item gains emphasis instead of losing it
Photo cardA gentle zoom of the image inside its frameMovement inside the card, layout untouched

These aren't hypothetical. Anticode's design systems use versions of them: buttons brighten slightly by default, outline buttons in the Luxury system fill on hover, Brutalist buttons, which carry a hard offset shadow, shift towards it on hover, header links move from the muted text colour to the full one, and product photos scale up a few percent inside their frame. The design article on hover effects for websites goes further into choosing one.

Hover isn't the whole story

Phones and tablets have no hover, and keyboard users never trigger it. So a hover state can only ever be an extra. The state that must exist is visible keyboard focus, which the publish-time design gate requires; see the visible keyboard focus check. A sensible habit is to style hover and :focus-visible together where it suits, so pointer and keyboard users get the same signal, and never to hide information (a price, a description) behind hover alone.

What the check doesn't do

  • It doesn't block publishing. It's one of the Critic's nineteen design checks, reported in the Report tab. The design gate doesn't enforce it.
  • It doesn't measure contrast. A fade to 0.95 opacity fails just as a fade to 0.4 does. Read the rule and decide whether it matters in your case.
  • It doesn't judge the alternative. A page with no hover states at all passes this check. The check only flags opacity; it doesn't ask for anything in its place.
  • Design-engine pages only. The check runs on Anticode page builds, not model-written apps.

Questions people ask

Is changing opacity on hover always wrong?

Not always, but it's the weakest common choice because it lowers contrast at the moment someone is about to click. The opacity hover check flags it so the decision is a conscious one.

My hover changes the colour and the opacity. Why does it still fail?

The check fails any hover rule that sets opacity, even alongside other changes. Remove the opacity declaration and keep the colour change.

Do hover effects matter if most visitors are on phones?

They matter less, since touch screens have no hover. That's why visible keyboard focus is required at publish while hover style is only reported.