Color accessibility beyond a pass/fail

Lauren Jong
San Francisco Digital & Data Services
9 min readJun 28, 2019


Accessibility for people with low vision is an important goal for, the City’s website. So I started where many people start — by checking our colors against the WCAG standards. Our team’s mission is to go above and beyond on accessibility, so of course we wanted to not just meet the required AA rating, but also achieve the AAA “gold standard”.

Turns out, this is really hard. Many of the things we wanted to do with color did not pass AAA. We had to make trade-offs, and balance decisions that are complicated, nuanced, and not black and white (pardon the pun).

In this post, I’ll go over some basics of how color contrast works, and then get more detailed about what that meant in practice. In many cases, it’s more complicated than achieving a simple pass/fail. But if you want to go beyond the standard, you need to understand it first.

First, a little background info

Color contrast is covered in the Web Content Accessibility Guidelines 2.0 (WCAG) in section 1.4.3. It says that to pass AA,

“The visual presentation of text and images of text has a contrast ratio of at least 4.5:1”, with exceptions for large text, logos, and inactive or meaningless text.

What actually is a contrast ratio?

This requirement is based on contrast ratios, but to many people, the contrast ratio is a black box. Using one of the many contrast ratio calculators, you input your colors and it spits back a score that tells you whether you pass or fail. If you’re like me, you’re wondering what’s behind that.

Screenshot from the WebAIM Color Contrast Checker…it passes! Yay!

So how is it calculated? Well, the answer is a lot of math. But the basic theory is that the color contrast ratio is a comparison of the luminance of the foreground color against the luminance of the background color. Luminance is the amount of light that a color emits.

According to WCAG, the specific cutoff of 4.5:1 was chosen because it “compensated for the loss in contrast sensitivity usually experienced by users with vision loss equivalent to approximately 20/40 vision.” And likewise the AAA level compensates for 20/80 vision.

It goes on to say “people with more than this degree of vision loss usually use assistive technologies to access their content.” In other words, the requirements focus on making things accessible for people who typically don’t use special low-vision software, like screen readers, contrast-enhancers, or magnifiers.

4.5:1 is not the only ratio that matters

It’s simple to remember that colors must meet the 4.5 to 1 ratio, but there are also different requirements for different sizes. There are three contrast levels that WCAG uses to define the requirements, 7:1, 4.5:1, and 3:1.

Here are examples of grey shades that meet each of those contrast ratios:

Depending on your contrast ratio and whether you are shooting for AA or AAA, WCAG requires a different text size:

Basically, larger text requires less contrast.

Defining normal and large

Normal and large text are defined by their size and weight.

Not actual size, but you get the idea

The problem is, as most designers can tell you, size and weight are not even standardized across fonts. Text in different typefaces may vary greatly in size, even if they are all set to 18pt.

All of these are the same font size, but some appear much larger. From top left counterclockwise: Rubik, Source Sans, Times New Roman, Merriweather, Crimson Pro, Open Sans.

Even fonts that take up the same real estate are not all equally legible. For instance, typefaces with a tall x-height have more distinguishable lowercase letters, which is a big driver of legibility.

Nor is there any standardization of “boldness”. A bold in one font may be akin to a regular in another font. Many typefaces today have a whole range of weights, not just bold and regular.

WCAG does note that “‘18 point’ and ‘bold’ can both have different meanings in different fonts but, except for very thin or unusual fonts, they should be sufficient.” I’m glad they recognize this issue, and for a general audience you probably don’t want to make it more complex. But designers trained in typography have more awareness of typeface legibility. They have the ability to apply their own sensibilities instead of relying on a blanket rule.

So, we’ve looked at how color contrast is calculated, and how it works together with size and weight to determine whether your text meets WCAG requirements. In the WCAG success criteria, you either pass or you fail. But it’s actually a nuanced gradient.

To look at only size and weight is very simplified. In these examples, the text on the left technically passes AAA while the text on the right does not, even though they are very similar:

And in these next examples, the text on the right is more legible. But because of the way it’s calculated, the increased legibility doesn’t get reflected in the WCAG rating:

If you’re only looking at the WCAG rating, you wouldn’t get any “credit” for the increased legibility of switching from Garamond to Verdana, for instance.

To be clear, I don’t mean to say that WCAG isn’t useful because of these “gotchas”. Having common standards is a great thing. They are a simple guideline that you can follow if you want some reassurance that you’re meeting basic best practices. Nor do I think that WCAG should address every one of these detailed aspects. That would be extremely complicated and would lose the simplicity of the current guidelines.

But behind that pass/fail score, there is a whole range of levels of accessibility. If you’re a designer looking to more critically address your accessibility, you need to keep all of this in mind and look beyond the requirements. In the spaces that the WCAG guidelines don’t cover, designers can use their expertise and judgement to make decisions.

This stuff is complicated.

Getting back to the design for the website, we had some very real tradeoffs to make as we iterated on the color palette.

Most of our body copy was set in Rubik 17pt, which is considered “Normal” in WCAG standards. This means we had to meet a ratio of 4.5:1 for AA, or 7:1 for AAA.

Here is the color palette, with potential text colors overlaid. Most of these combinations achieve a contrast ratio of 7:1 or greater, but I’ve noted in parentheses where it doesn’t.

Noted in parentheses are the contrast ratios for the combinations that aren’t meeting 7:1

Some of our decision making…

Font size

We actually considered switching our body font size from 17 to 18pt. A couple of our preferred color combinations were above 4.5:1 but below 7:1. Increasing the font size would have helped those colors to pass AAA.

We ultimately decided not to do that. With 18pt text we’d have a harder time using three-column layouts and maintaining a line length that is comfortable for reading, especially on smaller screens. Plus we knew that Rubik is a clear and legible typeface, so we felt comfortable falling a little bit short of the guideline.

Using text on L3 (dark) colors

Our preferred text colors on L3 shades have contrast ratios ranging from 4.31:1 to 6.82:1. If we wanted to meet a contrast ratio of 4.5:1, this would make the red and green backgrounds basically un-usable for text.

We really liked these colors, and didn’t want to completely give them up. They served a visual design function of highlighting content and creating hierarchy in a layout. And for our users, the colors reflected San Francisco’s progressiveness and inclusiveness.

The compromise was to create rules for where in our UI we use these combinations. We avoid body copy on these backgrounds but use them in our headers, which mostly have large headlines and other bold text. There, the size and thickness will increase readability. For level AA, large and bold text only need to meet 3:1, and we’re significantly above that.

Also, WCAG defines large text as 18pt. So with our headers as large as 62pt on many pages, we feel pretty comfortable using a slightly lower contrast ratio.

Darkening the purple

We looked into what it would look like for both the purple and blue to pass AAA on a white background.

Objectively, this made the blue, purple, and black less distinguishable from each other. On a more subjective level, it felt murkier and less vibrant. We didn’t feel this was a good tradeoff for passing AAA. Contrast isn’t just between background and foreground, it’s also between foreground elements.

However, we did feel that our original purple could be improved, especially with white text on a purple background. So we went halfway and made it slightly darker. This increased the contrast ratio from 4.58:1 to 4.96:1, but it doesn’t make any difference in our WCAG rating.

Using color for text hierarchy

We also wanted a lighter text color to go with our Slate blue. This could be used to create hierarchy between two pieces of text. There are many ways that designers can create hierarchy using weight, size, etc., but sometimes you need another lever to play with.

Although the 80% Slate has better contrast against white, it’s too close to the dark text. This loses the effect of creating hierarchy.

We ended up choosing 65% Slate. It has a good balance of a reasonable contrast ratio on white backgrounds, but also is distinguishable from 100% Slate.

Links on light and white backgrounds

My last example of making a trade-off is our links. We are willing to accept lower contrast with the background color in favor of links that contrast against other text. It’s important to us that people can quickly identify links and actionable elements on a page.

Although none of these pass AAA, you can see that their contrast ratios are closer to 4.5:1 and a healthy distance from 3:1 (the AA cutoff).

As a counterpoint, here’s an example where we made the opposite call. Bright blue on L2 backgrounds technically passes AA large text requirements. However…it is just barely passing. When we looked at it, it was clear to us that this wasn’t easily readable:

The link color is technically passing AA for large text, but we didn’t feel it is legible enough.

So on light backgrounds we use blue for links. But when the contrast is too low, it is better to use Slate (which meets our goal of 7:1) and distinguish links using only the underline.

For each of these decisions, we looked at competing and even conflicting factors. We took into account our values and goals for each piece of UI and weighed them together. We had conversations about how clear and accessible our content is, not just about what rating it achieves. While we often start by looking at color contrast ratios, in the end it’s a careful deliberation of many of these trade-offs.

PS. We’re hiring. 🎉 Come work directly with City departments and residents to build services from the ground up. We’re looking for designers, content strategists, developers, and product managers! Check out our open positions.



Lauren Jong
San Francisco Digital & Data Services

Previously at City and County of San Francisco Digital Services, Google.