Description
We've got several in-flight proposals for functions that can take "whole property value" arguments, like mix()
, random-item()
, etc. (And now custom functions and mixins, which @mirisuzanne and I are looking into more seriously again.) Because these arguments can potentially contain commas (say, mixing between two background-image lists), we can't use commas as the argument separator, and the proposals currently all use semicolons as the separator instead, as this is guaranteed to never show up at the top-level of a property value.
Even tho I'm the one that started this trend, I don't like it. ^_^ I'd like to find a different solution. The problems are:
- It's obviously a bit inconsistent with existing functions. It's not terrible, but it's not good either.
- A lot of userland tools use very simplistic parsers, and divide properties by just splitting on semicolons. This'll break them until they rewrite to be aware of nesting levels for matched parens.
- Most uses of these functions don't need the special separator; it's only the rare uses that involve operating on an entire comma-separated list that do. Forcing people to do a weird thing for a case they'll rarely hit isn't great.
- It's not forward-compatible in some cases. We have to design this syntax into the function right from the beginning, and can't ever expand an existing comma-separated function into it (unless we do a grammar split, which is nasty in its own way).
- The
var()
function already lets you take this kind of argument, but because its syntax was designed to take only one, and as the final argument, it can continue to use comma separation. (That is, you can writevar(--foo, blue, red, black)
- that's two args, a-foo
and ablue, red, black
list.)
The obvious solution is to add an optional wrapper around arguments, which will "hide" the commas from the outer function. It would only be necessary when someone is actually passing a comma-separated argument.
I have two possible suggestions, and am happy with either:
- Use
[]
, likebackground: mix(50%, url(start), [ url(foo), url(bar) ]);
- Use a new, generically named function, like
item()
:background: mix(50%, url(start), item( url(foo), url(bar) ));
This notation would only be allowed in the functions that can take these problematic values, and if present, would be stripped for the purpose of the actual value. No nesting - if you were mixing a subgridded "line names only" value for grid-template-columns, for example, you'd write it as grid-template-columns: mix(50%, [[foo bar]], [[baz qux]])
, so the outer []
gets stripped and the inner []
is part of the actual value.
(I'm rejecting using naked ()
for the same reason we ended up switching away from them for grid lines - it would mess up Sass syntax, and possibly others, hardcore, since in Sass it indicates math. I'm rejecting {}
for "naive userland tools" reasons; again, many just split the text with regexes, and stray {}
can screw them up. They're already potentially broken for custom props containing these chars, of course, but that's not an official Part Of CSS like this would be.)
Thoughts?
Metadata
Assignees
Type
Projects
Status
Unsorted regular
Status
Thursday morning