Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-color-6] color-extract() function to extract individual color components #6937

Open
LeaVerou opened this issue Jan 9, 2022 · 8 comments

Comments

@LeaVerou
Copy link
Member

LeaVerou commented Jan 9, 2022

In #5782, I discussed how we need ways to extract individual components so that authors can do truly custom things with colors.
While the Relative Color Syntax (RCS) offers maximum flexibility when it comes to a single color, we still don’t have a way to generate colors from color channels of more than one color. E.g. the hue and chroma of colorA and the lightness of colorB or the color of colorA and the alpha of colorB (didn't we have a CSS WG resolution that needed this?). The old syntax of color-mix() could do some of that, but in a rather confusing and awkward way, so we had decided to axe it in favor of a future syntax to cover these use cases.

Early thoughts about this centered around having separate functions (e.g. lch-hue()), possibly added on a use case basis.

However, I now think we should instead introduce a single color-extract() (name TBB) function that extracts any color component, from any color space.

Potential syntax could be color-extract(<color-space> <component> from <color>). Return value is identical to the value of <component> in the corresponding color function's RCS.

Reasoning:

  • Return values, color space ids, and component names are all well defined already by existing syntax, so incremental implementation and spec effort would be relatively small
  • The main argument against a generic function is its verbosity, but given that all common use cases are covered by RCS and color-mix(), this is reserved for the niche use cases, which could use more verbose syntax.
  • Since all components of this syntax refer to existing tokens, the syntax is automatically updated for new color spaces, or even custom ones.
@LeaVerou LeaVerou added css-color-5 Color modification Agenda+ labels Jan 9, 2022
@tabatkins
Copy link
Member

Grammar looks good to me. 👍

Given the fairly limited use-cases (generally design systems that can hide away the complexity in custom props), I'm okay with the verbosity. It seems commensurate with the use-case.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed CSS Color 5, color-extract(), and agreed to the following:

  • RESOLVED: Add color-extract() to Color 5 and continue work
The full IRC log of that discussion <fantasai> Topic: CSS Color 5, color-extract()
<fantasai> github: https://github.com//issues/6937
<fantasai> lea: Had discussions in the past, especially after Web Almanac
<fantasai> lea: when we saw that authors are often generating color variations by extracting color components and doing math on them
<fantasai> lea: we have relative color syntax for most of these use cases, already implemented in Safari
<fantasai> lea: however, don't have a way to combine components from multiple colors
<fantasai> lea: these are much more rare, but they do eist
<fantasai> lea: there was even a WG resolution for how to express a thing, which required combining output of one color and components of other color
<fantasai> lea: color-mix() used to be able to to do that in an awkward way, which we removed
<TabAtkins> (We ended up doing something different, but yeah it was part of Forced Colors Mode.)
<chris> q+
<fantasai> lea: at first Chris and I were thining to add e.g. lch-lightness() etc on a use-case basis
<fantasai> lea: but now thinking why not have a generic extraction function
<fantasai> lea: extra effort in terms of spec and implementation shouldn't be too high
<fantasai> lea: main argument is it's very verbose, but for common cases have other methods
<fantasai> lea: so I think the extra verbosity is OK
<fantasai> lea: and Tab already said he agrees with the idea in the issue thread
<smfr> q+
<Rossen_> ack chris
<fantasai> chris: I think it's verbose, but it makes sense and is clear
<fantasai> chris: i like re-using existing things like color space and components, etc.
<TabAtkins> yeah +1 to it, and i'm happy with how it slots into the color() component naming stuff
<fantasai> chris: Lea, you have component there, in Colro 5 have custom components for custom spaces , could you re-use?
<fantasai> lea: yes, could re-use
<fantasai> chris: great, I like the generality
<Rossen_> ack smfr
<fantasai> smfr: I'm trying to figure out is this an API for converting APIs between color spaces?
<fantasai> lea: no, this is an API for doing custom math with color components, that is more general than relative color syntax
<fantasai> chris: No if you want to convert color spaces, can already do that and it's very simple. But it gives you a complet color
<fantasai> smfr: if conversion under the hood and picking out components
<fantasai> smfr: should this just be a typed OM thing?
<fantasai> lea: JS API?
<fantasai> smfr: oh, this is a CSS API
<fantasai> smfr: I need to read the issue
<Rossen_> q?
<fantasai> chris: I agree the Color API should have the same functionality
<dino> q+
<fantasai> dino: Would be great to see an exampe in the gh issue of actually doing a design or palette with the color-extract() syntax
<miriam> +1 I like this proposal, and would use it
<florian_irc> fantasai: we should come back to this next week after people have time to read and think some more
<fantasai> fantasai: Seems like people need more time to review, maybe revisit next week. Seems likely to have support though.
<lea> +1
<fantasai> Rossen_: Seems we might be able to record a resolution today actually
<astearns> proposed resolution: accept the work in color-5
<fantasai> Rossen_: Any objectionsS?
<chris> syntax actually looks good to me, and tab already said he liked it
<fantasai> RESOLVED: Add color-extract() to Color 5 and continue work

@LeaVerou
Copy link
Member Author

LeaVerou commented Jan 12, 2022

Example of creating a new color with the alpha of one color and the components of another:

--color3: lch(
	color-extract(lch l from var(--color1))
	color-extract(lch c from var(--color1))
	color-extract(lch h from var(--color1))
	/
	color-extract(lch alpha from var(--color2))
);

This makes me think of two obvious improvements:

  • A syntax to extract multiple components, and have color-extract() return a sequence of tokens
  • If the component is alpha it should not require a color space

These would bring it down to:

--color3: lch(
	color-extract(lch l c h from var(--color1))
	/
	color-extract(alpha from var(--color2))
);

Note that in that case we need to either introduce some kind of separator, or disallow from as a component name.

@svgeesus
Copy link
Contributor

Example of creating a new color with the lightness and chroma of one color and the hue of another:

--color3: oklch(
	color-extract(oklch l from var(--color1))
	color-extract(oklch c from var(--color1))
	color-extract(oklch h from var(--color2))
	/
	color-extract(lch alpha from var(--color1))
);

@svgeesus
Copy link
Contributor

why is this lch and not in lch like the other places that describe the color space for processing?

@LeaVerou
Copy link
Member Author

in lch is a <color-interpolation-method> token. We are not interpolating anything here.

@svgeesus
Copy link
Contributor

Ah, fair enough

@svgeesus
Copy link
Contributor

Moving new feature requests to CSS Color 6, to stabilize CSS Color 5 which is about ready to move to CR.

@svgeesus svgeesus added css-color-6 and removed css-color-5 Color modification labels Jan 26, 2023
@svgeesus svgeesus changed the title [css-color-5] color-extract() function to extract individual color components [css-color-6] color-extract() function to extract individual color components Mar 8, 2024
@LeaVerou LeaVerou changed the title [css-color-6] color-extract() function to extract individual color components [css-color-6] color-extract() function to extract individual color components Apr 2, 2024
@svgeesus svgeesus assigned svgeesus and unassigned LeaVerou Aug 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants