WCAG 2.2 sets contrast as an exact ratio, not an impression: 4.5 to 1 for text, 3 to 1 for large text, and a separate 3 to 1 for non-text UI components — none of which “looks fine on my monitor” can actually verify.
I picked a grey for body text against a cream background because it looked fine on my monitor, in my office, at whatever brightness I happen to run my display. It looked fine to me for months. It did not look fine to a user who wrote in to say the text on one particular page was close to unreadable, and when I actually measured the two colours instead of trusting my own eyes, I understood why. Looks fine had never been a specification. It had been one person’s monitor and one person’s eyesight standing in for a standard.
WCAG 2.2 makes the standard exact rather than felt. Success Criterion 1.4.3, Contrast Minimum, sets the ratio at 4.5 to 1 for ordinary text and 3 to 1 for large text. That is not a suggested band, it is the pass line: measure a pairing at 4.4 to 1, a tenth short of the threshold, and it still fails, because the criterion’s entire content is a number rather than an impression of how close it looks. I had been picking colours by eye and assuming that if they read comfortably to me, they cleared whatever bar existed. There is a bar, and it is a ratio computed from two colour values, which means it can be checked exactly rather than felt approximately.
What I had missed entirely, not just under-measured, was the second criterion. Success Criterion 1.4.11, Non-text Contrast, sets its own 3 to 1 ratio for UI components and graphical objects against their adjacent colours: button borders, form field outlines, icons, anything that conveys structure without being text. I had been checking my body copy against its background and calling the page done, while a form field’s own outline sat at a contrast low enough that a user with reduced vision might not be able to tell where the field actually was.
The thing that actually changed my process is realising contrast is arithmetic, not taste. Given two colour values, the ratio between them is a single computable number, and a computable number is something you can gate on before a change ships rather than something you eyeball after it already has. My own perception of contrast is calibrated to one monitor, one ambient light level, and one set of eyes, none of which are the user’s, which makes looking fine to me one of the least reliable checks available for something the standard has already reduced to a formula.
Once the check existed as a script rather than a habit, I ran it retroactively across every page already shipped, not just the ones I was actively building, and it surfaced pairings I would never have caught by revisiting them from memory. A muted label colour introduced well over a year earlier, reused since across a dozen components, sat under the text threshold the entire time, unnoticed because nobody had looked at that specific pairing since the day it was chosen. A ratio check does not care how long a colour has been in production or how many times it has quietly passed an unspoken visual review. It either clears the threshold or it does not, on every page it appears on, today as much as the day it shipped.
So I compute the ratio for every foreground and background pairing before I ship it, against whichever threshold applies: 4.5 to 1 for text, 3 to 1 for large text or for a component border against what sits behind it. A pairing under the line is a fail, not a judgement call I get to override because it reads fine on my own screen. It is a small addition to a design review, and it catches exactly the kind of thing my eyes were never going to catch, because my eyes were never the instrument the standard was written to satisfy.