Re: [csswg-drafts] [css-color-6] color-contrast() should take transparency into account (#7358)

## Tree Climbing for Fun and 'Posits
Obviously, compositing over images and compositing over gradients bring up additional and not-well-resolved issues.

Something to point out here, the background color is commonly specified in an element that is much higher up the DOM tree than the text or other foreground color. Most of the time to do the calculation needed for the color-contrast() function, there will be the need to trace up the DOM tree for the corresponding color(s) at the given spatial coordinates.

**A background color with transparency is inherently ambiguous**, as it requires tracing back not only to the previous background color, if that color is also transparent than multiple steps up the DOM tree, **_but also_**, foreground colors, gradients, effects, not to mention what happens when a transparent background of a div is straddling multiple underlying backgrounds, or the more common instance of underlying images, all may have to be considered.

Since the APCA tool was mentioned, one of the reasons it presently only offers alpha for text: It's trivial to use a text color with transparency, if the background color is fully opaque. However it is quite far out of the question to take a transparent background color as there are too many variables without known constraints or rules as to what that transparent background color might be composited over.

### _Without knowing that fully, a transparent background color is ambiguous at best._

In the example below, admittedly a slightly contrived case for illustration purposes, the rasterizer is providing four different background colors behind one single text color, _not counting the image of course...._

**_Click for full size_**
<img width="350" alt="Transparent Background Examples The text below in Top Div uses a #fff9 background (sRGB, about 60% opaque or 40% transparent), and that div is itself on top of other divs with opaque color backgrounds but the divs themselves are each opacity:0.5 all on top of the main div bg image, and while unseen, the main divs bg color is #f7f which is obviously unrelated to the image. This text you're reading is #fff on a #0009 transparent background.
How should this calculate?
TOP DIV: Hello, and thank you for reading, Ill be your top div today, and todays special entree is the transparent background behind this text drizzled onto the chefs special foie gras backgrounds with more transparency, all resting on a bed of a savory ratatouille body. The big question is at what point does that make the background color as calculated here inappropriate or incorrect in terms of determining contrast? BLUE DIV: DIV WARS Episode I: The Transparent Menace ... Hey look at me! Im a transparent div with some text inside of it! RED DIV: Nice texting kid dont get cocky, you aint the only one in the galaxy thats transparent! Spatially, I texted Kessel while running a 12 parsec marathon!" src="https://user-images.githubusercontent.com/42009457/219278620-c55867cc-c2ef-4aea-8892-dcc41e7423d1.png">


Calculating contrast for each pixel is awfully expensive, but there's something more important that needs to be discussed. 

Both the div called "Top Div" and the first explanatory div, have their backgrounds set at 60% opacity or 40% transparency. The BG color for the first one is black with white text, the BG color for "Top Div" is white with black text.

The readability and the _apparent opacity_ is quite different between the two. The _linear_ opacity is being applied to gamma¹ encoded sRGB color values while compositing.

Here is the same example except that foreground and background are reversed for the two top most divs. 

**_Click for full size_**
<img width="350" alt="Transparent Background Examples The text below in Top Div uses a #0009 background (sRGB, about 60% opaque or 40% transparent), and that div is itself on top of other divs with opaque color backgrounds but the divs themselves are each opacity:0.5 all on top of the main div bg image, and while unseen, the main divs bg color is #f7f which is obviously unrelated to the image. This text you're reading is #000 on a #fff9 transparent background.
How should this calculate?
TOP DIV: Hello, and thank you for reading, Ill be your top div today, and todays special entree is the transparent background behind this text drizzled onto the chefs special foie gras backgrounds with more transparency, all resting on a bed of a savory ratatouille body. The big question is at what point does that make the background color as calculated here inappropriate or incorrect in terms of determining contrast? BLUE DIV: DIV WARS Episode I: The Transparent Menace ... Hey look at me! Im a transparent div with some text inside of it! RED DIV: Nice texting kid dont get cocky, you aint the only one in the galaxy thats transparent! Spatially, I texted Kessel while running a 12 parsec marathon..." src="https://user-images.githubusercontent.com/42009457/219281601-cc31a406-414a-42ff-af51-1be72dedfcc0.png">

Here's an extreme close-up of the upper and lower div's text, Side by side for comparison.

**_Click image to zoom_**
<img width="161" alt="60% Wbg Btxt 60% Bbg Wtxt ZOOMED" src="https://user-images.githubusercontent.com/42009457/219283373-8d92f147-f38e-41c2-a9ce-375b0b8603c0.png">

And we haven't even talked about other possible transfer modes. The point I'm getting who here is the additional ambiguity that arises from making the background color transparent, when a solid background should be the foundation that text is displayed upon.

### Some thoughts
What I hoped to illustrate above more than anything else, was that doing automated color with transparent backgrounds has potentially very poor results, unless some reasonable constraints or rules are applied.

There are certainly plenty of good uses for having selectors that are set up with transparent backgrounds for elements in a design system. But the issue that comes up is the one we discussed last year, that of automated adjustment. Automated means that no human is looking at it to evaluate or make the adjustment. As such:

- **Background colors need to be composited before a contrast value can be calculated.**
- Transparency as currently defined/calculated per CSS is linear, not perceptually uniform, and is applied to gamma encoded colors (not linear), such that a given opacity value does not provide perceptually consistent results.
    - this is particularly of concern when switching from **light mode to dark mode**. Transparency which works for a pair of colors in light mode very likely will not work the same way when reversed for dark mode.
- For any automated control, and the color-contrast() function is an automated color control, it can be difficult to determine what a background color is going to be if it has any transparency.
    - sampling every pixel is computationally wasteful unless done at the rasterizing stage, which means that determining contrast would have to be deferred until then, which IMO is not a viable option.
    - even then, what would be done if there were multiple contrasts within a div that text was on? Or it's on an image? Such busy backgrounds should not be used with text, as [**I describe here with examples.**](https://tangledweb.xyz/busy-background-breaks-bulletin-f4ff4bf67e5a)
    - compositing over an image isn't bad per se, but in practice frequently _**is bad**_, and frequently does create poor results.

## _Key takeaway_
If a human designer is evaluating, that's one thing—but for an _automated tool_ that deals with color appearance, then a means must be provided to replace the **eyes of a human designer** with that of a **standard observer**.

If that's not directly possible or practical, then appropriate rules must be in place to constrain the use of transparent backgrounds.

**_Example of a reasonable rule set:_**
1. The background color _underlying_ a transparent background must not itself be transparent.
2. The element containing the transparent background must be fully enclosed by the element which has the fully opaque background.
3. When used over an average image, and text is black, then BG:
    - `#ffffff` opacity must be greater than 0.7
    - `#a0a0a0` opacity must be greater than 0.9
    - in-between values interpolated 
4. When used over an average image, and text is white, then BG:
    - `#000000` opacity must be greater than 0.5
    - `#909090` opacity must be greater than 0.8
    - in-between values interpolated 

<sub>_Disclaimer: these opacity values have not been thoroughly evaluated, and should not be considered normative, only here as an example for this discussion._</sub>

## TL;DR
Transparent backgrounds present a lot of problems for any automated color adjustment control. The potential for misuse and abuse is great. If the use of transparent backgrounds is to be permitted in conjunction with automation, reasonable constraints need to be in place.

Thank you for reading

Andy

----
<details><summary>
TANGENTIAL FOOTNOTE: ¹</summary>
1) re "gamma" — yes I'm quite well aware that sRGB technically uses a piecewise tone response curve for _encoding_, not a simple gamma. Nevertheless gamma as an _"all inclusive meaningful term"_ is the simple, industry standard convention for discussion purposes, at least here on the West Coast, and Hollywood in particular. Between saying _"piecewise tone response curve"_ and _"gamma"_, which one is easier to say/work with? Particularly when everyone in the industry knows that's what's meant.

And it's useful to point out, the IEC sRGB spec _specifies_ the EOTF as "a simple 2.2 exponent", and the piecewise is only there for mathematical convenience and intended to be as close as possible to the simple 2.2 exponent. The piecewise does have added benefits for _encoding_ when the  display is using a simple exponent EOTF. The piecewise should preferably be used for _decoding_ for image processing purposes to prevent round-trip problems. But _image processing needs_ are not the same as sending something to a display or emulating the characteristics of a display.

_**Copypasta from that document:** (emphasis added)_
_...This standard dramatically improves the colour fidelity in the desktop environment...the input and output device vendors...easily and confidently communicate colour without further colour management overhead in the most common situations. The three major factors of this RGB space are the colorimetric RGB definition, **the simple exponent value of 2.2**, and the well-defined viewing conditions, along with a number of secondary details necessary to enable the clear and unambiguous communication of colour..._

It's nevertheless true that the IEC made some non-normative, opinion comments in the appendix, regarding the use of the term "gamma", but that appendix aside, use of the term continues in general discussions in industry for reasons already outlined.

This [related thread at ACEScentral](https://community.acescentral.com/t/srgb-piece-wise-eotf-vs-pure-gamma/4024) is quite interesting, and includes comments by Jack Holm.
</details>

-- 
GitHub Notification of comment by Myndex
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/7358#issuecomment-1432740199 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Thursday, 16 February 2023 09:00:37 UTC