Menu

Search toolsChangelog

to move to openDescribe the problem, not the tool

guide

Contrast is not average brightness

A colour can look bright because one encoded channel is large and still have less relative luminance than a duller-looking colour. WCAG contrast starts by converting sRGB values back to proportional light, weighting the channels and comparing two luminances. Average RGB and visual adjectives answer different questions.

Three numbers that are not light meters

The six digits in a hex colour are three encoded sRGB channel values. #808080 means that all three encoded channels sit near their midpoint. It does not mean the display emits half of white’s luminance, because sRGB uses a transfer curve designed for storage and display behaviour rather than linear arithmetic.

That is the first reason average RGB fails. The second is weighting: human visual sensitivity is not equal across red, green and blue. WCAG relative luminance uses 0.2126 for linear red, 0.7152 for linear green and 0.0722 for linear blue. A blue-heavy colour and a green-heavy colour with the same channel average can therefore need different text.

Before you read on

Two colours have the same average of their encoded red, green and blue values. Must they have the same WCAG relative luminance?

  • The encoded channels are not linear and their luminance weights differ.

  • Exactly. Equal encoded averages do not imply equal proportional light.

  • The container does not change the WCAG formula for the colour values.

No. Each sRGB channel is linearised first, and the resulting red, green and blue values receive different weights. The average throws away both facts, so it cannot substitute for relative luminance.

Contrast belongs to a pair

Once a colour’s relative luminance L is known, its ratios against the two extremes are:

black contrast = (L + 0.05) / 0.05
white contrast = 1.05 / (L + 0.05)

One rises with L and the other falls. Their crossover occurs when both are the square root of 21, about 4.58. That explains why an opaque sRGB swatch always has one black-or-white choice above 4.5—but it does not explain whether a translucent overlay, disabled state or photograph behind the text will preserve that pair.

The colour palette file maker performs this comparison for every named swatch and exports the winner beside the colour token. It refuses alpha-bearing hex because contrast would then depend on an unentered background.

A palette is not a component audit

The ratio is necessary evidence, not a complete interface. Normal and large text have different WCAG targets. Focus indicators, icons, borders and state changes have other requirements. Font rendering can also make very thin text harder to read even when the mathematical colours meet a threshold.

Use a measured token to avoid an avoidable colour mistake, then test the real component in every state. Converting a PNG to JPEG or WebP can change storage and occasionally pixel values; it does not create a semantic foreground-background relationship or certify text embedded inside an image.

Common questions

Is a higher RGB average always a lighter colour?

Not in the measurement used for contrast. Encoded channels must be linearised and green carries much more weight than blue, so equal averages can produce different relative luminance.

Does one of black or white always pass 4.5 to 1 on an opaque colour?

The stronger of the two has a theoretical minimum of the square root of 21, about 4.58 to 1. That covers the numerical normal-text threshold, but the real component can still fail through opacity, imagery, states, anti-aliasing or using a colour different from the measured token.

Can converting an image improve the contrast of text inside it?

A format conversion does not redesign the pixels. Lossy encoding can soften edges or alter samples slightly, but it cannot turn inaccessible embedded text into a reliably accessible foreground-background pair.

Tools for this

Sources