DEV Community

Benjamin Olsen
Benjamin Olsen

Posted on Fully Autonomous

A passing contrast ratio is the start of a button check

A button can pass a color-contrast calculation and still be difficult to use.

The calculation answers a narrow question: how much luminance contrast exists between the specified foreground and background colors? It does not tell you whether the control has a useful label, visible focus or enough space when text grows.

Here is a small workflow for keeping those checks separate.

Begin with a known pair

Use black text on white as a sanity check:

Text:       #000000
Background: #ffffff
Contrast:   21:1
Enter fullscreen mode Exit fullscreen mode

The current version of my checker returned 21.000:1 for this pair. That is a known example, not a claim that the whole tool or your website has passed an accessibility audit.

Now enter the exact colors used by your button. Do not estimate them from a screenshot if the CSS values are available.

The W3C explanation of minimum contrast describes AA requirements for text: generally 4.5:1, or 3:1 for qualifying large text. Large text means at least 18pt, or 14pt bold—approximately 24 CSS px or 18.67 CSS px respectively. A small button label does not qualify simply because its font looks bold.

Check the states you render

Create a short record before changing colors:

State Text color Background Other check
Default Actual CSS value Actual CSS value Label is readable
Hover Actual CSS value Actual CSS value Label remains readable
Keyboard focus Actual CSS value Actual CSS value Focus is visible

If hover changes the background, check the new pair. If it changes opacity, the rendered result depends on what is behind it; an opaque HEX-pair calculation is no longer the complete picture.

Keep focus visible without relying on hover. This gives a starting point to inspect:

.action {
  color: #000;
  background: #fff;
  padding: 0.75rem 1rem;
  border: 2px solid currentColor;
}

.action:focus-visible {
  outline: 3px solid #000;
  outline-offset: 3px;
}
Enter fullscreen mode Exit fullscreen mode

The outline still needs to be checked against the actual surrounding surface. This snippet is not a universal focus-indicator solution.

Add the non-color checks

Use Tab to reach the control and confirm that focus is visible. Activate it using the expected keyboard interaction for its element type. Increase text size and inspect wrapping. Read the label out of context: “Send project enquiry” communicates more than “Click here.”

Use a button for an action and a link for navigation. A good color pair cannot repair the wrong interaction semantics.

Record what passed

Write “text/background pair passes AA normal-text contrast,” rather than “button is accessible.” The narrower statement tells the next person which question was actually answered.

I maintain the free Color Contrast Checker. It compares solid, opaque sRGB colors and previews the pair. Images, gradients, transparency, keyboard behavior and the rest of the page need their own review.


Disclosure: I maintain the linked tool or kit. This article was prepared with AI assistance. Practical checks are identified separately from illustrative examples; verify the result in your own project.

Top comments (0)