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-5] Commas in color-mix()? #6066

Closed
LeaVerou opened this issue Mar 2, 2021 · 13 comments
Closed

[css-color-5] Commas in color-mix()? #6066

LeaVerou opened this issue Mar 2, 2021 · 13 comments
Labels
Closed Accepted by CSSWG Resolution Commenter Satisfied Commenter has indicated satisfaction with the resolution / edits. css-color-5 Color modification

Comments

@LeaVerou
Copy link
Member

LeaVerou commented Mar 2, 2021

Since various UAs are currently implementing, it's imperative that we finalize the syntax of color-mix() ASAP.

I've done a fair bit of editing and clearing up of that section recently, and the current grammar looks like this (note that the adjusters have been removed per editor resolution):

color-mix( in <<colorspace>> && [ [ <<color>> && [ <<percentage>> ]? ] <<color>> ])

Valid usage examples per this grammar:

color-mix(in lch red 20% white)
color-mix(in lch 20% red white)
color-mix(red 20% white in lch)
color-mix(20% red white in lch)

Invalid usage examples:

color-mix(red in lch 20% white)
color-mix(red 20% in lch white)
color-mix(in lch red white 20%)

In previous versions of color-mix(), there were commas to separate the color space argument from the colors. After #6050 we resolved to remove that comma. However, since a comma is a "stronger" separator than a space, if we left the comma between colors, it would look as if the color space argument only applies to one of them:

color-mix(in lch red 20%, white)

So we removed that comma as well.
While I would strongly object to having a comma only to separate the colors but not the color space from the colors, I think the previous all-comma syntax was actually more readable:

color-mix(in lch, red 20%, white)
/* vs */
color-mix(in lch red 20% white)

OTOH this syntax allows for more flexibility in ordering the arguments.

@mirisuzanne
Copy link
Contributor

I tend to agree that the commas add clarity, and would favor that over flexible ordering. As mentioned in the linked issue (#6064), it seems important to me that we establish a relationship between the percentage and the color it applies to. I like that the comma syntax allows me to clearly see the difference between:

color-mix(in lch, red 20%, white)
color-mix(in lch, red, 20% white)

Ideally the colorspace could still be first or last (and eventually optional).

@svgeesus svgeesus added the css-color-5 Color modification label Mar 2, 2021
@svgeesus
Copy link
Contributor

svgeesus commented Mar 2, 2021

Yeah that is a big readability difference.

@LeaVerou
Copy link
Member Author

LeaVerou commented Mar 2, 2021

Ideally the colorspace could still be first or last (and eventually optional).

Note that with the current grammar it can also only be first or last, not in the middle.

@una
Copy link
Contributor

una commented Mar 3, 2021

Just wanted to bring up that this might be a bit confusing. in is already a CSS unit value (inch)

@emilio
Copy link
Collaborator

emilio commented Mar 3, 2021

I won't be in today's telecon because APAC, so I'll dump my thoughts here.

I do find commas way more readable as well for what is worth.

Ideally the colorspace could still be first or last (and eventually optional).

I'd prefer the order of arguments being as fixed as possible at least for now, actually. The stricter the grammar, the faster it's going to be to parse it, and the more we can extend it in the future without headaches. I'm thinking that there's some parallelism between the color-space argument to color-mix() etc and the direction argument of linear-gradient(), which is also only allowed at the beginning, before the color stops.

My preference would be to settle on something simple at first like color-mix(in <colorspace>, <color> <percentage>?, <color>), then figure out if/how we need to extend such syntax. If we fix the position of the colorspace we can also remove the in keyword of course, though that's more debatable.

@una
Copy link
Contributor

una commented Mar 4, 2021

To avoid the in keyword, why not use existing constructs like the /, i.e.

color-mix(red 20%, white / lch)

I do think the comma is necessary here to separate where the 20% belongs to

@LeaVerou
Copy link
Member Author

LeaVerou commented Mar 4, 2021

I think the in keyword adds readability: think of how we say things in English: "interpolate X and Y in LCH". I don't think any confusion with the in unit is likely, since units are prepended by numbers.

In your example @una, I would be unsure whether lch is grouped with white or with red 20%, white. E.g. in background, / has lower precedence than ,. If we use commas to separate top-level units, we should use it to separate all top-level units.

I'm fine with forcing the color space (and other future metadata) to be first. The downside is that it reads somewhat more awkwardly, the upside that it's more consistent with other functions this way (e.g. gradients).

@una
Copy link
Contributor

una commented Mar 4, 2021

The color-mix should take place in the same color-space, otherwise wouldn't this cause compatibility issues? I would expect that whichever colors I use in the color-mix, the mixing will be done in the same color space. The colors would get cast to that space and mixed.

That's why I feel that the most straightforward syntax is:

color-mix([ [ <<color>> && [ <<percentage>> ]? ] <<color>> ] / <<colorspace>>?)
color-mix(red 20%, white / lch)

This reads to me as: mix 20% red with 80% white in the lch color space

@svgeesus
Copy link
Contributor

svgeesus commented Mar 4, 2021

I would expect that whichever colors I use in the color-mix, the mixing will be done in the same color space. The colors would get cast to that space and mixed.

Yes, exactly.

@una
Copy link
Contributor

una commented Mar 4, 2021

Or we can swap the color space (though I prefer the color space at the end):

color-mix(<<colorspace>> / ?  [ [ <<color>> && [ <<percentage>> ]? ] <<color>> ] )
color-mix(lch / red 20%, white)

(apologies if this syntax is incorrect).

@LeaVerou
Copy link
Member Author

LeaVerou commented Mar 4, 2021

@una in your grammar there are no commas, but there are in your examples. Assuming the correct version includes commas:

I made this point earlier, but since it was in an edit it may have been lost. In background, / has lower precedence than comma. E.g. background: url(...) center / cover, black. I would be strongly opposed to using the same operators with different precedence in two different CSS properties, this is very internally inconsistent.

@svgeesus
Copy link
Contributor

svgeesus commented Mar 4, 2021

I do see an emerging consensus that commas are better, at least between the two color-percent pairs

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed Commas in color-mix(), and agreed to the following:

  • RESOLVED: Add back commas
The full IRC log of that discussion <Rossen_> Topic: Commas in color-mix()
<Rossen_> github: https://github.com//issues/6066
<fantasai> leaverou: Since we have rule that ? reptition should use commas but not other things
<fantasai> leaverou: we removed commas from color-mix because not a list
<fantasai> leaverou: but it doesn't read very nicely, and not clear which color the percentage belongs to
<fantasai> leaverou: so thinking to add the colors back
<Rossen_> q
<fantasai> leaverou: since we can't keep going back and forth about it, UAs are implementing
<fantasai> leaverou: Wanted to resolve this once and for all
<fantasai> leaverou: I also agree it's more readable with commas
<TabAtkins> q+ to agree
<una> q+
<fantasai> leaverou: I think it should have a comma to separate metadata from list of colors
<una> to also agree (we need commas)
<fantasai> leaverou: clarify whether about the first color or the function as a whole
<fantasai> leaverou: Seem to have consensus on adding them back
<fantasai> leaverou: Also, do we still have 'in' for color space?
<fantasai> leaverou: Seems like only have color space in the beginning
<Rossen_> ack TabAtkins
<Zakim> TabAtkins, you wanted to agree
<fantasai> TabAtkins: Agree with leaverou
<fantasai> TabAtkins: we're not attached to using commas everywhere like JS is
<fantasai> TabAtkins: only use it in some places
<fantasai> TabAtkins: It works reasonably here
<fantasai> TabAtkins: and helps with readability
<fantasai> TabAtkins: and we should also have the metadata in a single thought at the beginning, separated by comma
<fantasai> TabAtkins: consistent with gradients and shapes
<fantasai> TabAtkins: so +1 to what leaverou suggested
<Rossen_> ack una
<fantasai> una: I agree that commas are needed here
<fantasai> una: much like gradients
<miriam> +1 need commas
<fantasai> una: I also want to add, I don't think we need end keyword if we have this syntax
<leaverou> q+
<fantasai> una: I think we are reaching consensus in the issue, and +1 to proposal
<chris> s/end/in
<aja> fwiw, emilio landed on nightly, used commas, & % applied to 2nd color, "in srgb" at start or end. willing to change
<fantasai> leaverou: I would argue for 'in' keyword
<Rossen_> ack leaverou
<fantasai> leaverou: it reads better, and also lets us expand the syntax later to add more options
<fantasai> leaverou: So, makes it more readable and makes syntax less ambiguous, so argue to keep it
<fantasai> Rossen_: Seems like we have consensus around adding commas, any objections?
<chris> great, emilio already implemented what we are about to resolve <3
<fantasai> RESOLVED: Add back commas
<una> q+
<fantasai> Rossen_: Next one is do we want to have the 'in' keyword
<fantasai> una: I would like to object to it
<Rossen_> ack una
<leaverou> q+
<aja> chris, except for which color the percentage applies to
<TabAtkins> Also object, we don't use these sorts of intro keywords except absolutely necessary for disambiguation.
<fantasai> una: Reasoning, I don't think it's necessary and we don't have a construct of 'in' elsewhere in CSS, so introduces new concept not seen anywhere else and I don't think it adds clarity
<astearns> we have 'at' elsewhere
<fantasai> una: Don't want to add new syntax to CSS
<TabAtkins> Colorspace keywords are plenty clear and won't block our extensibility in the future.
<fantasai> Rossen_: OK, I suggest we open a separate issue for this
<TabAtkins> astearns, yeah, that's for disambiguation
<TabAtkins> because there are two positions
<Rossen_> ack leaverou
<fantasai> leaverou: Using prepositions for metadata in functions is common in gradients as well, which is where I got the inspiration. But agree with separate issue.
<fantasai> TabAtkins: I'm happy to argue that gradients are special

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Closed Accepted by CSSWG Resolution Commenter Satisfied Commenter has indicated satisfaction with the resolution / edits. css-color-5 Color modification
Projects
None yet
Development

No branches or pull requests

6 participants