Myndex / SAPC-APCA

APCA (Accessible Perceptual Contrast Algorithm) is a new method for predicting contrast for use in emerging web standards (WCAG 3) for determining readability contrast. APCA is derived form the SAPC (S-LUV Advanced Predictive Color) which is an accessibility-oriented color appearance model designed for self-illuminated displays.
https://git.apcacontrast.com/documentation/APCAeasyIntro
Other
435 stars 14 forks source link

Light text on dark background #4

Closed tkeenoy closed 2 years ago

tkeenoy commented 3 years ago

I'm doing some evaluation of Material Design's standards around high-emphasis and medium-emphasis text. If you're unfamiliar, the spec uses rgba to allow the same css styling to scale along with background colors. e.g. a white text with .87 opacity will render as a lighter grey as the background color lightens. This helps developers use one style across many backgrounds and still maintain contrast (up to a point).

Under WCAG 2.0, the medium-emphasis style (.6 opacity) would pass AA or AAA for small text, but it pretty marginal under the newer proposed specs. I've attached a graphic showing findings. Each panel has: Material Design style | WCAG 2.0 ratings (small, large), APCA% Text color (including opacity) | Background color | renders-as color (actual output of computed rgba rendered on background) Recommended usage guidelines (note that "all" is misleading - this check is only intended for the scope of body text styles, so we're not talking about weights <300)

image

I was surprised to see that the Medium Emphasis styles (right column) that passed AA or AAA under WCAG 2.0 are more marginal under the proposed new spec. My understanding was that light text on dark backgrounds was being under-rated in the old spec, but these findings seem counter to that idea.

So I guess the "issue" is more of a question: am I doing these test correctly, and are the results as expected?

Myndex commented 3 years ago

Hi @tkeenoy

Really great questions! The answers are complicated, I'm going to try to be brief.

Under WCAG 2.0, the medium-emphasis style (.6 opacity) would pass AA or AAA for small text, but it pretty marginal under the newer proposed specs.

I don't see anything unexpected, especially in view of my reply to issue #3 a few days ago. I may have been unclear.

Remember that scoring for APCA is "within a certain percentage" depending on if you want to hit rating 4 or 3 etc. And contrast and the sliding scale font weight and size is a far more fluid and flexible paradigm.

Taking the 0.6 #42 #B3 case:

WCAG 2.x passes at AA for fonts down to minimum (8px) because that standard has no minimum. The APCA minimum for readable text is 12px, and with this color combo you need weight 700 @ 12px, and you'll still get a level 3 (debating regarding rounding up within 1%) and even so for normal weight anything less than 18px is really pushing it here. This is an "AA False Pass".

Yet in this edge case, AAA is a little stricter: It demands a normal weight font be 24px, but here the chart for APCA says 20px. AAA says a 700 weight font at 18.6px, APCA says 18px at 500 weight.

As I said a few days ago, 2.x degrades as colors get darker, and you get more false passes. No way should these colors be used for a normal weight font less than 18-20px. But AA says they can.

Text color (including opacity) | Background color | renders-as color (actual output of computed rgba rendered on background)

What are the font weights/sizes you are using in your examples?

Recommended usage guidelines (note that "all" is misleading - this check is only intended for the scope of body text styles, so we're not talking about weights <300) I was surprised to see that the Medium Emphasis styles (right column) that passed AA or AAA under WCAG 2.0 are more marginal under the proposed new spec.

First of all, they aren't "more marginal" they are more correct.

Those colors are horrible for small text, especially body text. They SHOULD fail.

My understanding was that light text on dark backgrounds was being under-rated in the old spec, but these findings seem counter to that idea.

The answer is more complicated than any sort of "always underrating." This is not an absolute metric between the methods, but the RELATIVE reverse contrast inside each method. On the APCA tool you can click the example ampersand to swap colors and see the polarity divergence. (2.x does not do polarity divergence at all.)

Next, keep in mind that we put 2.x and SAPC in a model together and fed them both the same random color pairs — thousands of 'em. No human involvement picking as a designer might, just random. In these tests, 2.x false passed 49% of colors, and false failed 22% (not even considering font variations). This naturally means APCA will fail more colors, but do so correctly, BUT ALSO: APCA will pass more colors and do so correctly. And with the added flexility of far wider font guidance.

An edge case like this 0.6 which is a horrible pair of colors for all but the larger and bolder elements, is not the place to see where APCA will pass what 2x did a false fail on — it's the opposite — this example is the edge where 2.x is false passing for AA, and APCA is saying "woah there young feller' them thar's too dark a' colors fer readin'".

> So I guess the "issue" is more of a question: am I doing these test correctly, and are the results as expected?

I don't see anything unexpected: APCA is correctly limiting font size on poor colors that 2.x was passing as AA. Colors that should not be used with small fonts, most especially not for body text.

WGAC 2.x math and methods are not perceptual, and it is not the touchstone to judge contrast prediction. APCA does not change the values of colors, it simply provides an accurate prediction of those color's relative perceptual contrast. You're going to drive yourself nuts trying to compare 2.x and SAPC. Please re-read what I wrote in #3 — WCAG compares only along a very narrow band.

Let's take the top right: it says that AAA small is passing. It shouldn't in theory, because It's "equivalent" of about 5.5:1. That said, taking it as 90%, reasonable minimum fonts are 22px at 300, 16 at 400. Yet "AAA" says you can go minimum, even 8 or 10px. SAPC says no, and so do I. 10px is below the critical readability size even for normal vision. 10px might as well be invisible to anyone with 20/40 and worse. And you can drive a car with 20/40.

Honestly your eyes are a better judge — the old math I think threw a lot of people off, and they followed the math results and not their eyes. "The Emperor Wears no Clothes" comes to mind. Put it behind us. As I mentioned in the other thread(s) the new scoring model is not a pass/fail, more of a rating. And it's designed to help existing WCAG 2.x sites pass at least at level 1, and "should be" no less than level 2 or level 3 if the background is #FFF.

It's not the color it's the weight

The new method is taking into account how we perceive contrast: at high spatial frequencies (i.e. thin small fonts) it's more about the weight driving a minimum color difference, or perhaps I should say the weight is the limiting factor. At lower spatial frequencies (i.e. big fat bold fonts), the contrast sensitivity curve flattens rapidly with higher color contrasts, but not so much the case with thin small fonts.

Here is your 0.6 #42 #B3 example, but with appropriately sized fonts (and "font smoothing" at default NOT blended antialiased which damages contrast by 20-30%).

Screen Shot 2020-10-12 at 2 07 55 PM

Notice how dependent the readability is on the size and weight here. Smaller samples at the myndex.com/SAPC/ tool.

More Problems than Just Color Choices

Added to this: browser rendering of thin fonts can be very inconsistent. Here's an extreme example. The Google Fonts font JOST. First, here it is rendered on Safari:

Screen Shot 2020-10-12 at 2 10 19 PM

Now, here it is rendered on the same computer and the same colors... but by Chrome:

Screen Shot 2020-10-12 at 2 11 05 PM

😮😳 Not all fonts are this inconsistent, but it points to one of the greater problems of general inconsistency among font families. In this case I suspect there is something technically wrong (maybe bad hinting?? Or wrong path direction?) but I have not examined it.

I hope that clarifies things. Please keep the questions coming, some of these will probably end up in a FAQ.

Andy "Color Obsessed Dude"

tkeenoy commented 3 years ago

Awesome, this clarifies things and helps flag the "false pass" issue. The greater granularity of size/weight also gives a lot more for a designer to work with than before. Rather than taking a whole chunk of stuff of various sizes and weights and slapping a .6 alpha on it and calling it done, I need to be a lot more particular about how and when I apply those modifiers. Great stuff.

Edit: realized I didn't answer your question: The header in each card is 24px Helvetica Neue Medium (500). The second and third lines are 14px Helvetica Neue Medium (500).

14px is the minimum size we normally display. We sometimes use 12px for data visualization labels.

joshuakraemer commented 3 years ago

I have also studied the Material design color recommendations for dark themes and have found them to be quite problematic.

For example, the page https://material.io/design/color/dark-theme.html#ui-application contains the following information about the "error color":

Error colors are used to indicate an error state. The Material baseline dark theme error color is #CF6679. image This dark theme color was created by taking the light theme error color (#B00020) and lightening it with a 40% white overlay, to pass AA-Level contrast standards.

The background color on this image is #292929. For #cf6679 on #292929, the SAPC calculator gives an Lc of only 34.9. The most saturated color with the same HSL hue as #cf6679 and an Lc of at least 60 is #ff9eb0, a bright pink. It just seems to be impossible to have red text on a dark or even completely black background with sufficient contrast (in sRGB space).

Material colors with a tint designation of "200" are recommended for text on dark backgrounds (see same page as above). I have examined all colors with a designation of "200" from the palettes found at https://material.io/design/color/the-color-system.html against the background color of #292929. Out of the 17 chromatic foreground colors, 10 gave an Lc of at least 60, 7 a lower value.

Other color themes/systems besides Material are problematic as well. For example, with GitHub's Primer ANSI color palette (https://github.githubassets.com/app/app/assets/stylesheets/custom/github/checks.scss), only 3 of 6 chromatic text colors give an Lc of at least 60. With the well known Solarized dark color palette (https://ethanschoonover.com/solarized/), all color combinations give an Lc below 60 (highest is just 40.0).

Myndex commented 3 years ago

Hi Joshua @joshuakraemer

Yes, pure sRGB red (#f00) and also pure blue (#00f) should never be the brightest of a color pair if the contrast is important for readability. In the case of blue, it is because blue is very low resolution, very low luminance, and S cones (blue) are not even present in the foveal area (center vision).

In the case of red, it is in part because red is also fairly low luminance, but more importantly because some vision impairments, particularly protanopia, have significant difficulty seeing pure reds. While the red primary in sRGB is actually a red-orange with a dominant wavelength of 611 nm, as it is already at a low luminance, the 65% (ish) perceptual reduction for someone with protanopia makes it very hard to see.

THE PROBLEM:

WCAG 2.x contrast is actually incorrect, especially for dark color pairs, and many inverted colors. APCA fixes these and other issues. For red, here's a comparison:

••••••••••••••••••••••••••••••••••••••••••

EXPLAINER

••••••••••••••••••••••••••••••••••••••••••

Let’s start with how WCAG 2.x handles red.

Keeping in mind that a protan sees sRGB red at ~quarter the luminance, or perceptually 65% darker.

WCAG 2.x says this is a pass:

Gross. And nearly invisible for the protan:

image040

Not much better with normal polarity:

And still nearly invisible for protan:

image042

But if we make the text LIGHT instead of DARK then we can read far better….

….. Except ….. WCAG 2.x FAILS IT….!

And in THIS case, protans actually get BETTER contrast….

image044

DESPITE failing WCAG!

Here we just barely fail the 4.5 level…

….WCAG 2.x fails it for normal text.

Compare THIS FAIL to the “passing” 4.53 example at top as processed for CVD simulation:

image015 (WCAG 2.x fails the readable example on top, but PASSES the unreadable version beneath.)

And again, here protans are actually helped, but with colors that WCAG FAILS.

The moral of this story: WCAG 2 harms protans (and others) with both false passes and false fails.

••••••••••••••••••••••

SAPC G Series

••••••••••••••••••••••

The current APCA does better, these examples were done using the newer G series constants.

SAPC G-Series Exponents for APCA

Same exact color pairs as used above.

SAPC-G reports lower contrast for lower contrast colors Lc 32.5 is roughly equivalent to WCAG 2.x “1.65 to 1”... that’s a far cry from the 4.5 to 1 that WCAG 2.x actually reported for this same color pair.

Now let's go the other way, reverse light text on dark, but now the darker color is the red. This example at the same Lc value as the red on black:

Screen Shot 2021-04-02 at 11 10 54 AM

WCAG 2 reported this as 2.4:1 We have it at Lc 32.5, the same as the darker reverse text.

Here’s a side by side compare, Lc -32.5 top row, Lc -32.5 bottom row:

Lc 32 5 Compare

And finally, the color pair WCAG 2 reported as 4.43 to 1 is reported by the G series as Lc -71.3 which WCAG 2 should call "about 6 to 1" instead of failing it.

Screen Shot 2021-04-02 at 11 12 41 AM

And that concludes today’s edition of “Way More About Some Random Color Than You Ever Wanted To Know"

I have two gists that get into the comparison further:

Part I:Orange You Wondering About Contrast? Answering some contrast questions, and demonstrating a real solution to the infamous orange conundrum.

Part II:The Lighter Side of Dark Backgrounds An article comparing some parts of APCA with the old WCAG 2 contrast methods.

Thank you!

Andy

joshuakraemer commented 3 years ago

Thanks again, Andy. Let me add that blue light is also more likely to be scattered, which makes me believe that the contrast of blue text will become even worse if viewing distance is increased.

But does that mean that red and blue text on dark backgrounds should be banned completely? I think there are still valid reasons for using such color combinations at least for some text elements, for example because of branding or adherence to standards/conventions (like ANSI terminal colors). In such a case, a compromise is necessary between the right color and readability/contrast. For instance, in case of red, such a compromise would be somewhere between a real red with insufficient contrast and a bright salmon/pink with sufficient contrast:

dark_40 dark_60 (#‌ff3737 and #‌ff9191 on #‌000000, Lc according to SAPC 0.98G)

It is obvious that the APCA and SAPC algorithms are much better than the old WCAG algorithm to assess contrast in such cases.

However, I wonder if the above example with dark red on black (Lc = -40) is really as bad as the algorithm suggests (disregarding color vision deficiencies). If I compare that combination with a red on white of similar Lc, my impression is that the first combination has significantly better contrast:

dark_40 light_40 (#‌ff3737 on #‌000000 and #‌ff9797 on #‌ffffff, Lc according to SAPC 0.98G)

Myndex commented 3 years ago

Hi Joshua @joshuakraemer thanks for commenting

Thanks again, Andy. Let me add that blue light is also more likely to be scattered, which makes me believe that the contrast of blue text will become even worse if viewing distance is increased.

Blue refracts at a different angle than red, and so focuses at a different point. S cones are not in the foveal center vision, and are very sparse in the peripheral areas. The blue resolution is a fraction of red/green.

But does that mean that red and blue text on dark backgrounds should be banned completely?

YES. Banned completely, they are not accessible, and problematic even for normal vision. If either red or blue are to be used on a dark background, green needs to be added to boost the luminance.

I think there are still valid reasons for using such color combinations at least for some text elements,

No.

However, I wonder if the above example with dark red on black (Lc = -40) is really as bad as the algorithm suggests (disregarding color vision deficiencies). If I compare that combination with a red on white of similar Lc, my impression is that the first combination has significantly better contrast:

(#‌ff3737 on #‌000000 and #‌ff9797 on #‌ffffff, Lc according to SAPC 0.98G)

No, it does not — while it may seem that way in the very narrow use case you are using as an example, there are many more use cases where that is not true. It is definitely not true of the overall page is brighter for example.

SEE:

Screen Shot 2021-04-06 at 12 51 37 AM

APCA is doing a number of compromises to allow for the many possible variations, AND the many various impairment types. This is about accessibility, and as you can see below, the #‌ff3737 on #‌000000 is nearly invisible to someone with protanopia, which is 1% of the population.

It is certainly easy to look at these edge cases and see some minor discrepancies, this is due to the number of compromises needed to make a useful general standard.

Pure blue is absolutely prohibited as the brightest of two colors, as this is inaccessible for all vision types. Pure red is also prohibited as the brightest of two colors as there are a number of use cases and impairments where accessibility is detrimental.

Yes, if the entire page is black, and you are in a dark enough environment, and there are no bright elements on the page, then pure red on black is somewhat readable IF the font is very large and bold. Except for protanopia, for whom it is nearly invisible.

It is even worse for the newer color spaces like Rec 2020, where the red primary is literally invisible to protanopia.

You have young eyes — you are not going to be able to judge adequate contrast just by looking at it. Contrast sensitivity increases for the first twenty years of life... and after age 40 decreases. The APCA guidelines are not targeted at people with healthy perfect vision between the ages of 20 and 40. It is targeted at all sighted users.

BUT ALSO: critical contrast for fluent readability is a minimum of ten times the legibility JND. When we are talking about minimum contrast for text for fluent readability, pure red and of course pure blue are absolutely prohibited as the brightest of two colors. Even for normal vision, pure red on black with a small and thin font, is not nearly enough contrast for fluent readability.

I hope this clarifies the basis for these guidelines.