Re: [csswg-drafts] [css-variables?] Higher level custom properties that control multiple declarations (#5624)

Easiest solution is to just give them the same value they'd have in MQs. Not the most useful, but not *useless*, and solves the problem in a familiar way.

-----

Some more detail on the proposal, as I understand it:

* We introduce a new class of property, the "const property" (name up for Bikeshedding). Const properties have an open-ended namespace, like custom properties, but have a very restricted value space - probably just `<number> | <custom-ident>`, with some restrictive additional rules that prevent using any sort of reference, like var() or attr(). 
* Const properties inherit. (But don't inherit into shadows - see below.) 
* Const properties have some sort of identifying prefix, similar to but separate from the custom property `--` prefix. (Maybe just `const-*`.)
* We also introduce a ":const() pseudoclass" that can do simple conditional matching on the value of a const property. (Equality and lt/gt is all that's needed, I think.)
* Const properties are resolved in a completely separate selectors+cascade pass, preceding the standard cascade. During this initial cascade, the const pseudoclass never matches. 
* The results of this cascade pass are recorded, then normal selectors+cascade are run for all the other properties, during with the const pseudoclass can match. The const properties are *not* cascaded in this step; they retain their value from the first pass.
 * Yes, this means you *can* write code that attempts to set a const property based on a :const() pseudo matching, like `div:const(foo:1) { const-bar: 2; }`. It just won't have any effect, since the rule won't match during the first cascade, and the `const-bar` declaration won't do anything during the second cascade.
* Const properties *can* be substituted into any other non-const property using `var()`. This has standard IACVT behavior, so we don't have to invoke a *parser* pass after the const cascade.

There's strong use-cases for setting const properties on sub-widgets based on const properties set on the widget itself. (Set a widget to "dark mode", and it sets its sub-widgets to "dark mode" as well, using whatever property name they expect; etc.) I think we can get away with leaning on Shadow DOM for this:

* Const properties do *not* inherit into shadows.
* But the values of a const property on a host element *are* made available to the shadow tree. When the shadow tree is doing its initial const-cascade to resolve its const properties, the const pseudoclass is allowed to match based on the *host element's* values. (Or possibly we have a separate ":host-const()" pseudoclass to handle this, I haven't given enough thought to the design yet.)
* To make it easy to forward values to widgets actually handling a certain task, the const property grammar also has some substitution feature, like `host-const()` or something, that subs in the value of a const property from the host.

(Without shadow DOM, we'd have to define some notion of "iterate until stable" that I'm much more afraid of.)

----

I believe this sketch avoids any circularity issues while still addressing the majority of use-cases adequately.

Ultimately, this should put us at the same *functionality* as just using attributes, but with a substantially better user interface, as you can set const properties across your page with a bit of simple CSS, rather than writing JS and *very carefully* tracking state mutation so you can add/remove/change the attributes.

-- 
GitHub Notification of comment by tabatkins
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/5624#issuecomment-770108145 using your GitHub account


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

Received on Friday, 29 January 2021 23:45:26 UTC