Skip to content

[css-color-6] contrast-color() MVP in Level 5 #9166

Closed
@LeaVerou

Description

@LeaVerou

In the NYC F2F in 2022, we discussed defining an MVP of contrast-color() that would only return black or white depending on what color text is most readable for the background color passed. This would address the most common use case where authors have a dynamic color (often user selected) and need to display text on it. Currently authors need to know a lot about a11y and color theory to calculate this reliably, and more often than not the result is suboptmal. You can see an example in this very page:
image

However, the only relevant resolution was this one:

RESOLVED: We have an unspecified default, the best available to the UA, which gets updated, only allowed when there aren't any candidates. If you include any candidates, algorithm is mandatory

But this only defines defaults, not a path for UAs to implement an MVP of this while we settle the details of the extended syntax. For this to happen, the simpler syntax needs to sit at an earlier level of CSS Color. UAs are extremely keen to ship an MVP for this and have been since 2022, so it's about time we settle on it, without being distracted by the multitude of issues for the extended color-contrast() syntax. Out of these issues, only these need to be resolved for this MVP, and none of them is really a roadblock:

Apart from those, we'd need to also decide on the syntax, which should be much simpler to do for this than for the extended case, since the point of this is to reduce the number of knobs authors have to understand and tweak and just do the right thing automagically, in line with the TAG principle on balancing simplicity and complxity.

I would propose just contrast-color(<color>) in Level 5 (since it's not CR yet) where:

  • Contrast algorithm is UA dependent (for background, this is the result with various existing algorithms, though UAs have also been doing their own explorations when they implemented accent-color). Yes, there is a concern that authors might be unhappy with the text color changing from white to black as UAs refine their algorithms, but remember this would only happen in case it improves the result. From conversations with Chrome folks, it appears they are happy to go this route (and have been taking a similar approach for other high level properties, e.g. text-wrap: pretty), hopefully other implementors share the same sentiment.
  • <color> is assumed to be background and the function returns white or black depending on which one produces the highest contrast for text (choosing white if there’s a tie). Yes, we have a resolution that it should be mandatory to specify whether the color argument is foreground or background, but in doesn't really make a difference here, so it would be unfortunate if authors had to add this noise everywhere.
  • If people are worried about syntax lock-in, we could even use an entirely different function name. E.g. max-contrast-color(<color>) or just max-contrast(<color>) since for every color, either white or black produce the maximum contrast. Or name it in a way that indicates it returns a foreground/text color.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions