Re: [csswg-drafts] [css-color-5] color-mix to allow more than two colors? (#4711)

# 

This is mostly a discussion of multiple color mixing. 

**the TL;DR is:** outside of a completely new space for the purpose, n-color mixing needs to be a cascade, where we only mix two colors at any one time. Conveniently this also means mix percentages can apply to color(1) only. The previous color-mix() will always be color(2).

_...And.... I just saw that una is suggesting something similar to what I wrote below. Doh me. At the end of the post though is an outline of some other color-mix() things, probably for separate issues._

----

### RGB is not paint
1) In additive _tristimulus_ color models (i.e. RGB), colors do not mix like "paint."

2) In an _additive_ model like RGB, the more random colors you add together at once, the closer the result color is to an achromatic grey. 

3) To create a means for color mixing of n-colors that functions in a useful and intuitive way is non-trivial, and also will be opinionated — oil pigments mix very differently than watercolors, which are different than printer inks, and different than...etc etc.

### Tristimulus Mixing
In an sRGB monitor, only three "colors" are emitted. A blueViolet, a limeGreen, and a redOrange. These "primary colors" are not chosen to be at the peak sensitivity of either the L, M, or S cones, but chosen to be as far apart as practical so they each primary stimulates one of the L,M,S cones as "independently as possible" (which is harder than you might think).

Thus, all the monitor/system is doing is selectively stimulating the LMS cones to create a particular color sensation. When you see YELLOW on the computer monitor, the monitor is only emitting GREEN and RED, at the same time in close proximity. This stimulates the L and M cones in a manner similar to actual yellow, which wavelength-wise is "between" red and green.

![redgreenyellow](https://user-images.githubusercontent.com/42009457/109438317-4c048f80-79de-11eb-8a80-76fa4fc6cf2f.png)

In the example above, the yellow bar is nothing more than red and green at the same time and location. The red and green does not "mix in the air" and in fact the red and green do not mix on the eye's retina, but later through the neurologically based opponent color process and visual cortex color processing.

### I.e.: it mixes _only in your head_

So then the question is how to predict a desired perceptual effect of mixing 2+ colors. And here again the answer is opinionated depending on the specific use case: is the goal to emulate natural linear light? Or the perception of tinting a pigment? Is the goal to affect the perceived brightness (Q)? Or the perceived lightness(J) or only the hue without affecting the readability contrast...

Each use case just mentioned needs a different approach. Just performing this in a usefully predictable manner with only two colors is already challenging. But there are plenty of use cases where an end result does need more than two colors mixed.

### Use Case Examples
A simple example is the challenge of developing a dynamic color palette that maintains appropriate contrast values, and also properly accommodates the many focus or state changes in interactive content. That is, a button might be a color mix of two colors, but will also subsequently need an adjustment by mixing in a third color to indicate a state change. 

Another example: A number of color-mix() colors are used throughout a page. There is the option to adjust the entire page, such as giving it a more sepia tone by adding the sepia adjust as another color mix to the other mixed colors.


## Solution: _A Cascade of Colors_

A solution would be instead of attempting to mix n-colors all at once, is to cascade the color mix iterations, only doing two at a time... typically an artist will only be adding one bit of pigment at a time to a color mix, and doing so here should have more predictable and useable results. SO:

### Allow color-mix() to be Recursive.

Example: `  color-mix( yellow 25%, color-mix(aqua 30%, purple))  `

So, 30% aqua + 70% purple makes lavender, **_then_** 25% yellow + 75% lavender makes a less saturated and lighter lavender.

**Percentages and adding up to 100%**
- If we limit to two colors at a time, then only one percentage value is needed, for color(1) only. 
- Possibly one percentage value per color(1) component, so if in LCh, 10% 40% 50% means putting the hue halfway between C1 and C2, but mostly disregarding C1's lightness, etc.

----

## color-mix() Concerns Not Examined in This Post

**Some things I didn't get into, but may discuss elsewhere include concerns such as these:**
_(placing these here as reminders to me, or to stir some thoughts, or something)_

**Missing "mix" spaces??:**
- xyY
- LUV and LChuv and Lsh
- Jab & JCh

**Separating working space from color property space**
- While it may be convenient to specify the color property in LCh, there are a number of legitimate reasons to perform a mix in a different space
    - needing to mix the color in a linearized space like XYZ or linear RGB
    - wanting to use the straight line interpolation of the LAB cartesian space
- Similarly, a page might use hex values for colors normally, but want to perform the mix or blend in LCh or XYZ.

**Missing linearizing for RGB spaces?**
- can RGB colors be linearized prior to mixing?
- and then returned to sRGB?

**Gamut mapping choices?** For color-mix(), I didn't see choices for:
- gamut mapping type (perceptual, absolute, sat, lightness, etc)
- soft clipping, 
- range, or hi or low _LIMITING_

**Fallback color**
- What happens if a color-mix() fails? Is there a way to specify the fall-back?


Andy


_Andrew Somers_
_W3 AGWG Invited Expert_

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


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

Received on Monday, 1 March 2021 04:23:03 UTC