so tab today

@tabatkins
320 Followers
34 Following
57 Posts

was @tabatkins on Twitter, now am @tabatkins.com on BlueSky. Only on Masto rarely.

editor of many CSS specs; lover of games, kpop, and animals; promoter of base-6 as optimal human-oriented number base

Pronounsthey
Homepagehttps://tabatkins.com
BlueSkyhttps://bsky.app/profile/tabatkins.com
@JaneOri I think you have overargued yourself into confusion here. While the slightly different syntax behavior isn't ideal, I believe it's far less of a problem or confusion than you're implying here. In general it's meant to Just Work without having to think too hard about it. (500 char comment blocks aren't the best for talking about this, tho.)
@JaneOri The fact that the value is used as-as is, in fact, the point. I'm not certain why you think it would be useless? It's exactly as useful to take a font list as a single font.
@JaneOri It was definitealy not a "last minute" call. It was the result of a bunch of discussion, some on the list and a bunch internal, about how unused `if()` arguments (and unused fallbacks in several other arb-sub funcs) should behave. Without this behavior, there are reasonable `if()` functions you would be unable to write, as they'd be cyclic even though every possible branch, on its own, wasn't; meanwhile a similar `@container` would work fine, just be verbose.
@JaneOri Right, outside of arb-sub functions, we just treat property values (including any functions) as being opaque token streams separated by arb-sub functions. The arb-sub substitutes in, and only after that do we care about any parsing.

@JaneOri Purely as an author-expectation language design issue, I think there's reasonable arguments both ways.

I came down in favor of the behavior split so we *could* do short-circuiting. There's a more ideal CSS where this is more consistent across the board, but we work with what we've got.

@JaneOri For example, say you're going to use the second argument for a `font-family` value. You might *expect* people to just pass a single family name, but it would also be reasonable to pass a comma-separated fallback list. If you didn't anticipate that, your function would break; now, it works automatically.

@JaneOri The *secondary* benefit of it is predictability. When you write `--my-func(1, var(--arg), 3)`, you very likely expect the arg to set the second argument. But in the earlier pre-spread version, it `--arg` contains commas, it would set *multiple* arguments. You could defensively wrap it like `--my-func(1, {var(--arg)}, 3)`, but we don't expect people to remember to do that.

The new spread behavior makes it work as we think people will expect, by default.

@JaneOri The short-circuiting isn't really a speed benefit (tho it does accomplish that a little); instead, it prevents later *unused* variables from creating reference cycles that'll affect earlier variables.

Note as well that this isn't just custom functions, it's *all* "arbitrary substitution functions" - var(), if(), attr(), etc. Anything that can emit an *arbitrary* token sequence in any location has this spread behavior, now.

@JaneOri The need for an explicit spread, btw, is so that we can reasonably do short-circuiting, and avoid resolving variables/etc in branches of an `if()` that we aren't taking. To do that, we need to know the overall structure of the function ahead of time, so we can control what variables need to be substituted and when. The spread op skirts around that and just eagerly resolves the arb-sub function immediately.
@JaneOri The inconsistency is slightly annoying, but we were locked in by compat. If I could redo it, I'd make CSS vars respect commas in normal properties too, and require ... to expand out into multiple. (Tho that *would* require being a little more specific about function and property syntax structures; *all* functions would need to define an argument grammar as well as a normal grammar, like arb-sub functions now do.)