bgrins / TinyColor

Fast, small color manipulation and conversion for JavaScript
https://bgrins.github.io/TinyColor/
MIT License
5.08k stars 438 forks source link

New readability functions produce inferior results #92

Open RandScullard opened 9 years ago

RandScullard commented 9 years ago

The new readability functions from commit 09a8d35 do not work as well as the existing ones in v1.1.2 of TinyColor. Please see this jsFiddle: http://jsfiddle.net/2sok91dg/1/

The left column is generated via the v1.1.2 mostReadable function, while the middle column is the new function from commit 09a8d35. As you can see, the new mostReadable function frequently chooses dark text on a dark background -- as dark as luminance 0.1892. The result is very poor readability with many colors, and the reason is simple math: The new function is based on contrast ratio, and the contrast ratio (as defined in WCAG Version 2) is higher for a dark color vs. black than for a dark color vs. white.

For example, take a dark gray (luminance 0.2). Its contrast ratio vs. black is (0.2 + 0.05) / (0.0 + 0.05) = 5.0. Its contrast ratio vs. white is (0.2 + 0.05) / (1.0 + 0.05) = 0.24. This tells us that black text is a better choice, but anyone looking at these combinations will tell you that white is more readable.

I think the point here is that the WCAG formulas are intended to answer the question: Is this color combination sufficiently readable for a person with limited vision? NOT the question: What is the BEST text color for this background color?

My proposed solution is shown in the rightmost column. It uses the existing v1.1.2 mostReadable function with the new getLuminance function from commit 09a8d35. It chooses light text until around luminance 0.5, then switches to dark. This is intuitively the right behavior, and it is based on the definition of relative luminance as given in WCAG Version 2.

bgrins commented 9 years ago

Thanks for the report and the demo. @jladbury do you have any opinions about this?

jladbury commented 9 years ago

Looking at RandScullard's fiddle, I agree that his proposal results in much better readability in very many cases - for my eyesight, that is. I think the argument, such as there is, must be with the WCAG standards.

For convenience, I updated the fiddle to display the background and foreground colours along with the luminance - see http://jsfiddle.net/2sok91dg/4/ (you might need to resize the window to get the rows to line up correctly). Taking the example with background #808080, I personally much prefer the new proposal of a white font: but it only meets WCAG 2 AA large fonts, while a black font meets AA large and small and AAA large (I am relying on the tool at http://dasplankton.de/ContrastA/ to calculate).

Perhaps TinyColor could provide an option as to whether its readability functions should use the WCAG 2 standards, which presumably give the widest suitability for visually impaired users, or to use RandScullard's proposal, which at least two of us (me and him!), prefer.

Any change should, of course, be properly documented so users know the basis of the choices they are making and can judge for themselves whether it meets any legal requirements, such as the UK's Disability Discrimination Act (a useful rundown of which can be found at http://www.webcredible.com/blog-reports/web-accessibility/uk-website-legal-requirements.shtml).

I haven't looked at the code in detail, but it could be that the 'argument' comes down to a choice between WCAG 1 and WCAG 2, in which case any legal considerations would be much simplified and my preferred way forward would be for TC to provide a straightforward choice between the two. Before you ask though Brian, I don't have any time to do this for the foreseeable future. Perhaps RandScullard could do it?

RandScullard commented 9 years ago

@jladbury The WCAG 2 version of isReadable works great, it's just the current application of that function to mostReadable that creates a problem.

I think I have a solution: Change mostReadable to use a private definition of isReadable (the definition from my proposed version) to do the color-choosing, and then return an object with the chosen color as well as an isWCAG2Readable boolean flag, where this flag is set via the WCAG 2 version of isReadable.

This way, mostReadable will reflect the true situation: That in many cases, the best choice of text color is still not sufficiently accessible, and you need to choose a different background or increase the font size.

If you think this is worthwhile, I'll update the fiddle to demonstrate it. And if we ultimately agree on the new approach, I'll be happy to implement it and generate a pull request.

jladbury commented 9 years ago

@RandScullard I think the problem here is that what is 'most readable' for you and me (and, I would hazard a guess, to most people) is certainly not 'most readable' for some visually impaired people. How TC should cope with this situation is probably up to Brian . . .

bgrins commented 9 years ago

So just to be clear, is the proposal to modify mostReadable only to go back to sort of how it was pre-WCAG 2? And that the readability function wouldn't change?

jladbury commented 9 years ago

If mostReadable is to change, it should not 'go back to sort of how it was', but include a parameter to specify what behaviour is required: whether it should return the colour 'most readable' to most people, or to visually impaired people. (It seems to me that the WCAG2 standard seeks to achieve the latter, at the expense of the former). Give the caller the opportunity to say what is wanted!

The discussion at http://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html is informative, if a little opaque.

RandScullard commented 9 years ago

I disagree that WCAG2 "seeks to achieve the latter, at the expense of the former." If anything, WCAG2 wisely takes a very conservative position on the question of readability; for example, it points out that some users actually require low contrast.

WCAG2 doesn't prescribe a formula for choosing the "best" color combination for any audience. It merely prescribes a formula for determining whether a given color combination provides a sufficient level of contrast. By attempting to apply the latter to the former, you're going out on a limb unsupported by WCAG2.

jladbury commented 9 years ago

Yes, it's arguable about what WCAG2 seeks to achieve. Whatever it does seek, parameterising mostReadable's behaviour seems to me most suitable. Brian's call though . . .