[csswg-drafts] [css-mixins-1] Inheriting values with their types into a function (#12484)

tabatkins has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-mixins-1] Inheriting values with their types into a function ==
Currently, the execution model for custom functions is that their bodies are treated as style rules that apply to a "hypothetical child" of the element applying the function. (This makes lets us leverage inheritance, and generally works well.) But this presents us with a bit of a conflict:

1. We don't want "local variables" to conflict with properties used in the outer page. If the outer page has registered the `--foo` property with a `<color>` syntax, the function shouldn't need to be aware of that if it wants to use a `--foo` local variable to hold an intermediate number in a calculation (regardless of whether it's declared as an argument, or just used directly as a local).
2. We want *values* from registered custom properties that inherit *into* a function to know what their type is, so they can more reasonably be tested in `if()` (like, executing a `style(--foo: red)` test).

This isn't really handled by the current data model, I think; custom properties are treated as existing *permanently* and *statically* on the entire document. I think the right solution isn't too much of a change, tho:

* We say that the effect of a custom property registration is to *assign types to [declared values](https://drafts.csswg.org/css-cascade/#declared)*. When a property applies to an element, and it's a custom property with a syntax registration, the declared value gains type(s) according to the syntax registration.
* This type is carried by the value itself, not by the property, so as goes thru the cascading process, and then inherits into descendants, it retains its type.
* When a property *changes its registration* (such as during argument or body resolution in custom functions), that doesn't immediately change anything about the value, unless the property is used to produce a *new* declared value.
* The value can lose its type when substituted into something else; it's just a token stream then.
* The value's type is used when necessary to inform comparisons in `if()`/etc.

That is, if you have a `--foo` property declared as `<color>` in the outer page, and it inherits into your custom function without ever being overridden, it'll compare *as a color* in `if(style(--foo: red): ...)`. But if you set `--foo:rgb(255 0 0);` inside the function body, where there's no registration, it'll become an untyped value, and fail the comparison.

A quick wrinkle: in a test like `style(--foo: var(--bar))`, the substitution causes the --bar value to lose its type, but `--foo:` preserves `--foo`'s type, which still determines how to test the value, so an inherited `--foo: rgb(255 0 0); --bar: red;` will end up testing as true.

I'm not sure *exactly* where edits for this would show up, probably a slight mix between Custom Properties & Values and Mixins.

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/12484 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Tuesday, 15 July 2025 21:24:18 UTC