Which color format to use
Every format on the left describes the same color; they differ in what is easy to read and edit. Hex and rgb() are the universal interchange formats: every design tool, browser and platform understands them, which is why they are the safe choice for brand guidelines and design tokens. hsl() was the first attempt at a human-editable format, with hue, saturation and lightness, but its lightness is not perceptual: hsl(60 100% 50%) yellow and hsl(240 100% 50%) blue have the same L yet look wildly different in brightness.
oklch() fixes that. Its L is perceived lightness, C is chroma (colorfulness) and H is hue, in a space designed so that equal numeric steps look like equal visual steps. Changing L in OKLCH changes brightness without shifting the hue, which makes it the best format for building scales, hover states and dark-mode variants. Every current browser supports oklch() in CSS. lab() and lch() are the older CIE equivalents, used in print and color science. cmyk() here is a naive conversion for quick reference; real print output depends on the press's ICC profile.
The WCAG contrast rules
WCAG 2.2 measures contrast as a ratio between the relative luminance of the lighter and darker colors, from 1:1 (identical) to 21:1 (black on white). The thresholds depend on what the color is used for:
| Criterion | Applies to | Minimum ratio |
| 1.4.3 Contrast (Minimum), level AA | Body text and images of text | 4.5:1 |
| 1.4.3, level AA | Large text: 24px regular, or 18.66px (14pt) bold and up | 3:1 |
| 1.4.6 Contrast (Enhanced), level AAA | Body text | 7:1 |
| 1.4.6, level AAA | Large text | 4.5:1 |
| 1.4.11 Non-text Contrast, level AA | Icons, input borders, focus rings, chart lines | 3:1 |
The ratio is truncated, never rounded up: #777777 on white is 4.47:1, and that famous near miss fails AA even though it looks fine to many people. Transparent text is composited onto the background first, so a 60% opacity grey is judged on the color you actually see. Placeholder text, disabled controls and logos are exempt; everything else a user must read is not.
What APCA adds
The Accessible Perceptual Contrast Algorithm, developed for the next generation of guidelines, models how contrast is actually perceived. Unlike the WCAG 2 ratio, it is polarity-aware (light text on dark is treated differently from dark on light) and far more accurate for mid-tones and dark themes, where the WCAG 2 formula is known to pass pairs that are hard to read and fail pairs that are fine. APCA reports a lightness contrast value, Lc, from 0 to about 106. As a rule of thumb, Lc 90 suits long body text, Lc 75 is the minimum for body text, Lc 60 for content text larger than body size, Lc 45 for large headlines, and Lc 30 for placeholder and disabled text. APCA is not yet a legal standard, so check both: WCAG 2 for compliance, APCA for whether people can comfortably read it.
How the contrast fix works
The fix buttons keep the text color's hue and chroma and move only its OKLCH lightness, searching for the value closest to the original that reaches the target ratio against the current background. The result stays recognizably the same color, just darker or lighter, instead of being replaced by black or white. If no lightness can reach the target, for example a saturated mid-tone background that sits too close to the middle of the range, the tool falls back to black or white, whichever contrasts more. The tint and shade scale below uses the same space, so the 600 or 700 step of your brand color is often already a compliant text color on white.
Designing for color-vision deficiencies
About 1 in 12 men and 1 in 200 women have a color-vision deficiency, most often deuteranomaly or protanomaly, which reduce the ability to tell red from green. The simulations use the Machado, Oliveira and Fernandes (2009) model at full severity for protanopia, deuteranopia and tritanopia, plus full achromatopsia, and recompute the contrast ratio for each. Contrast based on luminance survives most deficiencies, which is exactly why WCAG measures luminance; the real risk is relying on hue alone. Never use color as the only way to convey meaning: pair a red error state with an icon and text, and give chart series different shapes or line styles as well as colors.