Contrast GridAA / AAA

Contrast Grid / Colour wall

Contrast for Buttons, Borders and Focus

Design controls whose text, shape, states and keyboard focus remain perceivable without depending on a single colour change.

Working premise

A button is not one colour pair. It has text, fill, boundary, focus indicator and several states, each adjacent to different colours. Review the component as a small state system rather than approving the default screenshot.

01

Separate text contrast from component contrast

Button text must remain readable against its fill. The component boundary or distinguishing visual information may also need contrast against the surrounding surface. A borderless control can still be clear through fill, shape and position, but the evidence should be deliberate.

02

Design focus as an adjacent-colour problem

A focus ring is compared with the colours it touches, which may include both the button and page background. A two-layer ring or offset outline can remain visible across light and dark contexts better than one brand-colour outline.

03

Do not encode state with opacity alone

Reducing opacity blends the control with whatever sits behind it and can collapse text and boundary contrast. Define state tokens against known surfaces, and preserve a visible difference for hover, pressed, selected and disabled states.

04

Test keyboard and forced-colour modes

Move through the actual component using a keyboard, zoom the page and inspect system high-contrast or forced-colour behaviour. Custom shadows and background images may disappear; semantic elements and outlines are more resilient.

Field checks

  • Measure text against the button fill.
  • Measure the meaningful boundary against the surrounding surface.
  • Test focus against every adjacent colour.
  • Provide more than colour for selected or error state.
  • Verify keyboard order and forced-colour behaviour.

Contrast calculations cannot determine whether a control is labelled, keyboard-operable, correctly ordered or understandable in context.

SignalRecordDecision use
Defaulttext, fill, boundaryrecognisable action
Focusoutline + adjacent colourskeyboard location
Statefill, icon, label, shapeperceivable change