We're currently missing a grammar combinator in CSS's property grammar syntax.
We can express "exactly one" as "a | b", and we can express 5 of the 6
possibilities in {0+, 1+, all}×{in order, any order}* . The one thing
we're missing is "1+, in order", which we can't write without
duplication and honestly confusing grammar.
For example, the syntax for background-position-x takes a side keyword
and/or a length/percentage. You can specify either or both, but can't
specify none. Today, that requires writing something like:
[left | right] |
[left | right]? [<length> | <percentage>]
I don't know about you, but I don't see that as saying "a keyword
and/or a length/percentage". It's hard to read, and means we're
duplicating terms in the grammar, making it larger and even harder to
read, or else requiring indirection through an intermediate grammar
production.
This sort of pattern appears all over CSS. For example, the <picture>
spec defines the author-conformance grammar of its sizes='' attribute
using CSS. It needs one or more "MQ + size" values, and/or a final
bare size, and currently has to do the duplication and non-obvious
structure as above.
The image() function is yet another example:
<http://dev.w3.org/csswg/css-images/#image-notation>. You specify urls
and/or a fallback color, and I have to duplicate some of the grammar
terms to make that happen.
I propose the combinator be named ??, and its precedence be set
between juxtaposition and &&. The reason for this name is one of the
other two syntaxes in the "in order" branch uses the question mark
(the other is juxtaposition, which uses no syntax).
I recognize that we don't generally want to add more ASCII grawlix to
things like our property grammars, but this is the last missing piece
in completing the set of useful combinators. Anything else would have
much harder time justifying itself, as it's not filling a hole but
forging something new, so we shouldn't fear this opens the door to
even more hard-to-read stuff.
Thoughts?
~TJ
* Syntaxes:
0+, any order: a? || b?
1+, any order: a || b
all, any order: a && b
0+, in order: a? b?
1+, in order: _____
all, in order: a b