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-variables] To what extent are substitution functions usable *in* substitution functions? #10947

Open
tabatkins opened this issue Sep 25, 2024 · 1 comment
Labels
css-variables-1 Current Work

Comments

@tabatkins
Copy link
Member

It's currently clear and well-defined how substitution functions work when passed in the <declaration-value> part of another substitution function. For example, var(--foo, var(--bar)) is just fine - it's a valid var() function, and during substitution, the var() in the fallback is substituted if necessary.

What's less clear (arguably undefined) is what happens if you use a var() elsewhere inside of a var().

For example, does this work?

.foo {
  --foo: , blue;
  color: var(--bar var(--foo));
}

Currently this doesn't work in Chrome, it's invalid.

What about this one, probably more reasonable?

.foo {
  --foo: --bar;
  --bar: blue;
  color: var(var(--foo));
}

This is also currently invalid in Chrome.

That second one is pretty unfortunate, I think, particularly when applied to the new substitution functions. For example, it's completely valid to write color-mix(var(--percent), red, blue), because color-mix() is a normal function. But mix() is a substitution function, so if mix(var(--percent), red, blue) doesn't work, that kinda sucks.


Since nothing is capable of containing mismatched braces of any kind, it's safe to tell exactly where a function ends. So we could seek to the end of the substitution function, and if we found more substitution functions in its contents, sub them in before validating the outer function's grammar.

Aka, from my first example, var(--foo var(--bar)) would work by first treating it like var(█████). Then it would examine the interior, finding a var(███). Examining that interior, it finds --bar, forming var(--bar). That's valid, so substitute it. Now the outer function's interior is --foo , blue, forming var(--foo , blue). That's valid, so we substitute it too.

This ensures that substitution functions act identical to non-subsitution functions, wrt using substitutions inside of them.

Thoughts? @andruud, specifically?

@andruud
Copy link
Member

andruud commented Sep 25, 2024

arguably undefined

Ooor, arguably defined. :-)

"If a property contains one or more arbitrary substitution functions, and those functions are syntactically valid, the entire property’s grammar must be assumed to be valid at parse time." https://drafts.csswg.org/css-variables/#arbitrary-substitution

The examples are not valid because they don't match the grammar of var(). This appears entirely intentional and sensible to me. I like how it works now, but I definitely see the problem with var() working differently in substitution functions and non-substitution functions. But, ugh, it would be very annoying if we can't select the substitution value (AKA evaluate the function) without first substituting the function contents. It's even more mucking about with tokens before getting to the actual point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-variables-1 Current Work
Projects
None yet
Development

No branches or pull requests

2 participants