Stockio

Button Hover Colors: Hover, Active, Focus and Disabled

Build a predictable interaction palette for buttons, links and controls. Learn how to separate hover, pressed, focus and disabled colours across light and dark themes.

By Jonah Weiss

Design Systems Lead ·

On this page

A button colour is not a single swatch. It is a small vocabulary that tells people what they can interact with, where they are, and whether an action is available. When every state is improvised separately, the interface starts contradicting itself: hovering can look like selection, while keyboard focus can disappear into a dark surface.

Start with roles, not darker hex values

Create a state inventory before adjusting colours. For each control, record its resting surface, label, border, hover treatment, pressed treatment, focus indicator and disabled appearance. Use the contrast checker to compare each label against its actual state background, then check the focus colour against neighbouring surfaces. A passing resting pair does not guarantee a passing hover pair.

Treat interaction states as semantic roles rather than a command to darken everything. A solid primary button may become darker on hover, but a quiet text button may gain a pale background instead. Both communicate increased emphasis without pretending to be the same component. Keep those relationships consistent across your product.

Begin with one primary button, one secondary button and one inline link. These expose most palette problems quickly. Record the chosen values alongside the design token principles, including the intended background, rather than publishing isolated colour chips that lose their meaning outside a component.

Separate hover, pressed and selected meanings

Hover signals that a pointer is over an interactive target. Keep the change noticeable but restrained: a small lightness shift, a tinted surface or a stronger border usually works better than replacing the brand colour with a different hue. Touch users may never encounter this state, so it must not reveal essential instructions by itself.

Pressed describes the brief period during activation. CSS calls this state active, which creates confusion with persistent navigation selection. Name tokens explicitly, such as button-primary-pressed and navigation-selected. A pressed button can deepen its surface slightly; a selected navigation item needs a lasting treatment that remains clear after the pointer leaves.

Do not assume a fixed numerical adjustment produces equal visual differences across colours. Yellow can lose legibility quickly when lightened, while blue may tolerate a larger change. Inspect perceptual relationships and verify the resulting pairs. A structured brand palette supplies candidates, not an automatic state algorithm.

For destructive controls, preserve the semantic family through every state. A red action should not turn neutral grey on hover merely because the secondary-button recipe uses grey. Conversely, avoid saturating every quiet destructive link; its resting emphasis should still fit the action hierarchy and surrounding content.

Give keyboard focus its own colour role

Keyboard focus answers a different question from hover: which element will receive the next keyboard action? Its treatment should survive simultaneous hover and pressed states. A separate outline is often easier to maintain than changing the button fill, because the underlying component can keep communicating its other state.

Choose a ring colour that works beside the page background and the component edge. On busy surfaces, a contrasting separator can help. Test actual compositions, including cards, banners and dark navigation bars. The WAI explanation of focus visibility provides useful context without turning palette work into guesswork about keyboard behaviour.

Use focus-visible when you want the browser to determine when a visible focus indicator is appropriate. Never remove outlines globally and hope a background tint replaces them. The MDN focus-visible reference explains browser heuristics and compatibility details.

A focus ring need not be the brand accent. A violet brand button may need a near-black ring on a pale surface and a pale ring in dark mode. Consistency comes from the ring's role, shape and placement, not necessarily from keeping one hexadecimal value everywhere.

Encode state colours without cascade surprises

Use semantic tokens for the relationships you decided, then apply them in a deliberate order. The following example keeps hover and pressed colours away from disabled controls and lets focus coexist with either state. Its values are starting points for testing, not a universal accessible palette.

.primary-button {
--rest: #1d4ed8;
--hover: #1e40af;
--pressed: #1e3a8a;
background: var(--rest);
color: #ffffff;
border: 1px solid transparent;
border-radius: 0.5rem;
padding: 0.65rem 1rem;
}
.primary-button:hover:not(:disabled) {
background: var(--hover);
}
.primary-button:active:not(:disabled) {
background: var(--pressed);
}
.primary-button:focus-visible {
outline: 3px solid #111827;
outline-offset: 3px;
}
.primary-button:disabled {
background: #e5e7eb;
color: #4b5563;
border-color: #9ca3af;
}

Avoid setting opacity on the entire disabled button as your default recipe. It blends the label, border and surface with whatever lies underneath, producing different colours on different containers. Explicit disabled tokens make the outcome more predictable and preserve control over text readability.

Native disabled controls and controls using aria-disabled have different behaviour. The latter still need activation handling and may remain focusable. Colour cannot implement a disabled interaction. Follow the MDN disabled attribute documentation when choosing the underlying behaviour, and keep your visual naming aligned with the implementation.

Review themes and combinations systematically

Build a small review page showing all states on every supported surface. Include a disabled primary button beside an enabled secondary one: if their prominence reverses, people may misread availability. Include a focused button inside a tinted card, not only on the default white canvas.

For dark themes, reselect state values rather than mechanically inverting them. A brighter hover surface can communicate elevation, while a darker pressed surface can feel recessed; either relationship needs evaluation in context. Review the broader dark-mode colour guidance before making every control brighter simply because the canvas is dark.

Test combined states deliberately. Hover and focus can occur together; pressed and focus can also coexist. Persistent selection may sit underneath either one. Write down which layer communicates each meaning so that a later stylesheet change does not accidentally erase the focus ring or selected indicator.

Finish with a short acceptance pass using mouse, keyboard and touch. Check forced-colour settings where available, and avoid relying on colour alone for selection or errors. A checkmark, underline or border can preserve meaning when colour perception or display conditions differ. Document exceptions alongside the palette so future components do not repeat the same investigation.

Key takeaways

  • Define hover, pressed, selected, focus and disabled as separate semantic roles.
  • Check foreground and background pairs in every state, not just at rest.
  • Keep a visible focus treatment independent of hover and pressed fills.
  • Prefer explicit disabled colours over whole-component opacity.
  • Review combined states and dark themes on real component surfaces.
Featured sponsor

Reach designers & developers at work

Put your product next to the tools people use every day. One sponsor per placement, no tracking pixels.

Become a sponsor

Keep reading

Related articles

More in Typography & Colour
Typography & Colour

10 Best Color Contrast Checkers for Accessibility

Find a contrast checker for colour choices in websites and apps, from quick foreground-background tests to browser and desktop audits, with practical advice for testing real interface states.

Includes: Contrast checkerNoor HaddadNoor Haddad
Typography & Colour

Font Weights for UI: Regular, Medium, Semibold and Bold

Assign regular, medium, semibold and bold to clear interface roles. Build a practical weight map, avoid synthetic surprises and test emphasis in real UI components.

Includes: Contrast checkerArjun RamanArjun Raman
Typography & Colour

Dark Mode Typography: Adjust Weight, Contrast and Size

Tune dark-mode typography without blindly thinning every font. Compare text contrast, stroke weight, size and spacing using realistic reading samples and device checks.

Includes: Contrast checkerNoor HaddadNoor Haddad
Typography & Colour

Status Colors in UI: Success, Warning, Error and Info

Create a distinct semantic status palette with useful foregrounds, backgrounds, and borders while keeping brand accents separate from functional meaning.

Includes: Contrast checkerJonah WeissJonah Weiss
Typography & Colour

Dark Mode Design: Color Choices and Contrast Ratios

Build a dark theme with clear surface hierarchy, measured text contrast, and preference-aware CSS that stays comfortable without sacrificing readability.

Includes: Contrast checkerJonah WeissJonah Weiss
Typography & Colour

Small Caps, All Caps and Eyebrow Labels in Web Design

Use uppercase labels without sacrificing readability. Learn how tracking, genuine small caps, language-aware casing, and clear hierarchy work together in web typography.

Includes: Contrast checkerMateo FernándezMateo Fernández