dequelabs / axe-core

Accessibility engine for automated Web UI testing
https://www.deque.com/axe/
Mozilla Public License 2.0
5.98k stars 776 forks source link

Axe fails parsing (OK)LAB & (OK)LCH colors containing 'none' keyword #4269

Open BenjaminAster opened 10 months ago

BenjaminAster commented 10 months ago

The CSS color functions lab(), oklab(), lch() and oklch() can contain the special none keyword as a "missing color component" which is treated special when interpolating colors, while simply treated as 0 otherwise (see specification). Axe fails parsing such colors.

color: oklch(0 none none);
color: lch(none 0 none);
color: oklab(0 none none);
color: lab(0 none none);
straker commented 10 months ago

Thanks for the issue. Axe-core uses colorjs.io to parse color spaces. It looks like there are a few open issues about supporting none, such as https://github.com/color-js/color.js/issues/368, but nothing specific about lab, oklab, lch, and oklch.

BenjaminAster commented 10 months ago

@straker I've made a quick demo to play around with this where you can change the foreground & background color of a paragraph live: benjaminaster.com/bugs/axe-none-colors

When audited in Chrome Lighthouse (which uses Axe under the hood), Lighthouse throws an error only when using (ok)lab/(ok)lch colors (e.g. oklch(50% none none)), saying "axe-core Error: Unable to parse color 'oklch(0.5 none none)'", which is rather weird because in Color.js' live playground, Color.js does seem to support parsing colors like oklch(0.5 none none) color.

On the other hand, Lighthouse recognizes hwb() colors containing none just fine. For example, hwb(50deg none 10%) (a light orange) on a white background makes for an "insufficient contrast ratio" warning whereas hwb(50deg none 90%) (a very dark brown) on a white background gives no warning, which is the expected behavior and means that Lighthouse is definitely able to parse a HWB color containing none. – BUT: The issue you mentioned (https://github.com/color-js/color.js/issues/368) is still open and in Color.js' live playground, hwb(50deg none 10%) does indeed not display the expected color (but falls back to black).

I might be missing something here, but there seems to be a rather weird disconnect between which colors Axe in Chromium Lighthouse succeeds to parse vs. which colors Color.js can parse.

straker commented 10 months ago

That is indeed interesting. Our code mostly uses colorjs to parse the CSS string for the color bits but does have an exception only for HSL as colorjs doesn't support rad or turn angles (at least at the time, I think they may now). https://github.com/dequelabs/axe-core/blob/develop/lib/commons/color/color.js#L60-L83. I'm not exactly sure why there would be a disconnect. If I get some time later I'll try a few different things in axe-core directly and see where the issue occurs from.