W3C home > Mailing lists > Public > public-css-archive@w3.org > May 2021

Re: [csswg-drafts] [css-color-4] Color modifications proposal: extending color functions (#3187)

From: aborayan1020 via GitHub <sysbot+gh@w3.org>
Date: Sun, 16 May 2021 03:33:23 +0000
To: public-css-archive@w3.org
Message-ID: <issue_comment.created-841760550-1621136002-sysbot+gh@w3.org>
> ## **Edit: Most current proposal [here](https://github.com/w3c/csswg-drafts/issues/3187#issuecomment-499126198)**, just go straight there unless you want to read the thread for historical reasons.
> 
> 
> 
> -------
> 
> 
> 
> The lack of a color modification syntax is one of the few things that authors still use preprocessors for, and severely limits what CSS variables can do. I'm going to post this proposal I've been thinking about for a while. It's by no means perfect, but perhaps it can get the discussion going, so we end up with something decent eventually!
> 
> 
> 
> ### Goals of a color modification syntax
> 
> 
> 
> - Setting any color coordinates for all color functions, either to absolute values or to values relative to the modified color (e.g. set to 0.3 or increase by 50%)
> 
> - Avoiding accidental gamut clipping. If a syntax converts to sRGB, it should be syntactically obvious that this is happening.
> 
> - Easy lighter/darker variants (tint/shade)
> 
> - Blending of two or more colors
> 
> - Getting white or black depending on which one contrasts better with the base color
> 
> 
> 
> ### Proposal
> 
> 
> 
> This is loosely inspired from the current practice of defining major theme colors as color components in a variable (e.g. `--color: 180, 60%`) and then using them in color functions (e.g. `hsl(var(--color), 90%)`). However, this is simple textual substitution, which is insufficient, and imposes constraints on how the base color is defined.
> 
> 
> 
> I’m proposing to extend all color functions to allow for a `<color>` argument. If the color argument is present, it is converted to the target color space of the function, then the remaining arguments set or modify its coordinates in that color space. A `_` or `same` keyword can be used to mean "no change". For example, if a function’s grammar is `<number>{3}`, it will become `<color>? (<number> | _){3}`.
> 
> 
> 
> For example, `hsl(red _ _ 90%)` would create an HSL color with a lightness of 90%, and the saturation and hue from the provided color.
> 
> 
> 
> Before any modification, the color would be converted to the target color space of the function used. This means that modifications using `hsl()` can be lossy (since the color would need to be converted to sRGB), but there is no such problem with `lab()` or `lch()`. However, any syntax that allows modifying HSL or RGB coordinates would have the same issue, at least this syntax makes the conversion more explicit.
> 
> 
> 
> Directly setting arguments is not sufficient for most modifications, since it cannot perform relative modifications (e.g. "increase L by 10%" instead of "set L to .3"), which are far more common use cases. Therefore, we need to introduce a syntax for relative modifications as well. 
> 
> 
> 
> Ideas for that:
> 
> - `rel(<percentage>)`: Multiplies the color component by `<percentage>`. E.g. `lab(red rel(60%) rel(100%) rel(100%))` would convert `red` to Lab, and then multiply its L by 60%.
> 
> - `up <percentage>`/`down <percentage>`: Relative addition/subtraction. The previous example would be `lab(red down 40% up 0% up 0%)`. Given the lack of commas that we recently introduced, I'm finding this hard to read, since the keywords are not visually grouped with their percentages.
> 
> - Defining keywords for each coordinate, then using `calc()`. E.g. the previous example would be `lab(red calc(.4 * l) a b)`. Seems the most expressive and flexible, but probably too messy to define.
> 
> 
> 
> With the syntax for relative modifications, this addresses most desired adjustments, and expands naturally with every new color function. Tint and shade could be relative modifications on `hwb()`, though adjusting the L of Lab/LCH is better as it's lossless (and produces fantastic results).
> 
> 
> 
> ### Benefits of this syntax
> 
> 
> 
> - Extends on syntax that authors are already familiar with. No need to learn different ways to refer to the same color components.
> 
> - Can be understood by anyone who understands the existing color functions, even if they are unaware that a modification syntax exists.
> 
> - Makes the target color space very obvious, since it looks like creating a new color
> 
> - Every new color function comes with new color adjusters for free, no need to learn anything new besides using the color function.
> 
> 
> 
> ### Drawbacks
> 
> 
> 
> - Does not address contrasting colors
> 
> - Does not address blending of two or more colors. Perhaps these could be defined as separate functions, maybe `cross-fade()`, since we need to address this for interpolation too?
> 
> - It’s easy to clip the modified color to sRGB, since authors are very familiar with HSL and many would use that. However, any color adjustment syntax that supports adjusting hue, saturation, lightness would have the same issue. At least this syntax makes it obvious that you are creating an `hsl()` color, with the gamut limitations that this comes with.
> 
> - Stupid lossy transformations can be defined, like `color(hsl(color(mycmyk .1 .2 .3 .4) mycmyk 60%) .4)`. However, a) any sufficiently powerful syntax will allow for silly things, and b) see point above.



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


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Sunday, 16 May 2021 03:33:25 UTC

This archive was generated by hypermail 2.4.0 : Tuesday, 5 July 2022 06:42:33 UTC