Yesterday I committed a few changes to the CSS Color spec that are proving a little controversial to people without any background on the changes. Hopefully this will help!
Specifically, I made it so that the rgb() function (and others) can now use the syntax rgb(0 255 0 / 50%)
for half-transparent green. Previously you'd write that as rgba(0, 255, 0, 50%)
. Why'd I make this change?
This is part of a general overhaul to how CSS defines functions that fantasai and I are pushing. The overall strategy is written up on our wiki, but the general idea is that CSS has some informal rules about how to organize things and use certain punctuation characters. In particular, in CSS properties we normally just separate values with spaces, relying on distinguishable syntax (like <string>
vs <number>
vs <length>
) or just careful ordering to keep things unambiguously parseable. We use punctuation separators only for very specific purposes: commas are used to separate repetitions of a base value (like layers in the background
property, or font names in the font-family
property), and occasionally, when we can't do anything better, a slash is used to separate two otherwise-ambiguous values (like font-size vs line-height in the font
shorthand, transition-delay vs transition-duration in the transition
shorthand, or the multiple pieces of syntax in a border-image
layer).
However, functions violated those rules. They used commas extensively and somewhat inconsistently, just to separate values from each other. On the one hand, this makes CSS functions look slightly more like functions in a traditional programming language; on the other hand, it meant you had to learn a different mental model of how CSS's syntax works, and type a bunch of comma characters that weren't actually necessary. fantasai and I have gradually come to the position that it's worthwhile to unify CSS's syntaxes, making functions more property-like. (Our position can be summed up aptly as "functions are just named chunks of CSS syntax".)
Color
So that brings us to the Color spec. Color 3 was already a function-full spec, and Color 4 more than doubles that number, adding hwb(), gray(), lab() and lch(), and color(). The first four of those look similar to the existing rgb()/etc functions, just taking a couple of numbers, so they were originally designed with the same syntax, separating every number with commas.
But color() was a bit more complex, more like a CSS property. It had to take a colorspace name, an arbitrary number of arguments to the colorspace, an alpha, then finally a fallback value in case the colorspace wasn't loaded or was invalid. Putting commas between every value there just got ridiculous, not to mention made it difficult to read; in particular, it was hard to tell where the colorspace arguments ended and the alpha began.
So, I opened Issue 266 about it, and discussion eventually led us to making it use CSS property syntax pretty much exactly: color() takes a comma-separated list of colors (each one serving as fallback for the previous), and within each color, everything is space-separated. Because colorspaces can take an arbitrary number of numeric parameters, the alpha value was ambiguous (hard to even tell whether or not there was an alpha at a casual glance), and so we employed the slash to separate it visually from the parameters.
At this point, tho, it was slightly weird to have this one color function use this particular syntax form, while none of the others used anything like it. Welp, all the color functions were on our wiki page's list of things to overhaul anyway, so bombs away! We went ahead and changed all the new functions to use the same syntax (all values space-separated, with an optional slash-separated alpha), and then added a new syntax variant to the old functions with the same form.
(I stress, this is a new variant syntax, not a replacement. All your old rgb(0, 255, 0)
code is fine and will never be incorrect. We're just classifying it as a legacy syntax; we've got a handful of those cluttering up CSS specs.)
So, now all the color functions use the same syntax form, and they all agree with our general push to make functions resemble properties more closely. It may feel a little weird at first, but I think you'll appreciate it as you get used to it (a few characters less typing, at the very least). And we've been edging this way for quite a while - as far back as linear-gradient() we were trying to use commas reasonably, with the complex sizing/positioning part up front completely space-separated and commas used only to separate the color-stop repetitions.
Even with the explanation here, this feels very backward to me. In every other language I touch, function parameters are separated by commas.
Rather than repeat myself, I'll just link to the previous discussion on Jen's blog where she asked for input on this question:
http://jensimmons.com/post/jul-14-2016/comma-separate-or-not-comma-separate
My comment there explains my thinking. The rest of the comments there all seem to favor commas for functions very clearly.
This seems like a bad change. :-(
Reply?
The article you linked doesn't seem to provide any reasoning though, it suggests that this change is merely for consistency. Tab brings up the concern that this color method combines two use-cases (allowing multiple colors which require multiple values each) which is a collision of commas-vs-spaces. If we retain commas, we still need to group them.
Reply?
Theoretically we could just let the fallback be a
<color>
, so you'd have to nest functions to get fallback. That'd be unambiguous even with promiscuous comma usage, but we avoid function nesting when we can reasonably do so, as it makes it harder to read and write.Reply?
Yes, awesome! Thanks for the explanation. This makes editing and reading CSS a bit easier. I think the best part is that every bit of consistency and clean up we can introduce to CSS makes it easier for newcomers to learn and stick with it.
Reply?