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

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

== [css-variables?] Higher level custom properties that control multiple declarations ==
Currently, custom properties can be used to hold small pieces of data to be used as parts of larger values. Despite being called custom properties, they are mainly used as variables. High-level custom properties that control a number of other CSS properties cannot be implemented.

Besides limiting regular CSS authors, this makes it impossible for custom element authors to follow the [TAG guideline](https://w3ctag.github.io/webcomponents-design-guidelines/#:~:text=Don%E2%80%99t%20use%20custom%20attributes%20for%20styling) to avoid presentational attributes and to use a custom property instead, except for very simple bits of data like fonts, colors, and lengths. For anything more complex, web component authors use attributes instead. 

Examples from a variety of custom element libraries: 

- [`placement` attribute](https://shoelace.style/components/tab-group?id=tabs-on-left)
- `size` attribute [in Shoelace](https://shoelace.style/components/input?id=sizes) and [in Spectrum](https://opensource.adobe.com/spectrum-web-components/components/tags/examples)
- [`pill` attribute](https://shoelace.style/components/input?id=pill) 
- [`orientation` attribute](https://lion-web-components.netlify.app/?path=/docs/forms-listbox--orientation-horizontal)
- [`left` attribute](https://opensource.adobe.com/spectrum-web-components/components/split-button)
- [`placement`, `offset`, `tip` attributes](https://opensource.adobe.com/spectrum-web-components/components/overlay)

I can collect more if needed. Currently, these are impossible to implement as CSS custom properties as each of these controls multiple declarations and/or the value of the attribute itself is not used anywhere *directly*. 

Some proposals focus on a JS-based way to monitor property changes [w3c/webcomponents#856], but that appears to be hard to implement. So, I'm wondering if we can address this from CSS instead, especially since it would also address a number of other use cases too (mixins!).

There are discussions in the group about inline conditionals [#4731, #5009]. If we were to have such conditionals, these would be *possible* to implement, but very painful (each declaration value would need to be one or more `if()`). I was wondering if there's any way we could simplify this. 

A pseudo-class such as `:if-var(<dashed-ident> <comparison-operator> <value>)` would solve this ideally, but would likely not be implementable due to cycles. OTOH we already do cycle detection for variables, so perhaps it is? If so, I can flesh out a proposal.

Otherwise, perhaps a nested `@rule` that is sugar for the multiple ifs? E.g.

```css
my-input {
 @if-var(--pill = on) {
  border-radius: 999px;
 }
}
```

Though without [nesting](https://drafts.csswg.org/css-nesting/), that would need to be repeated in each rule, so it would still be awkward for things like e.g. the tabs placement.

Whatever solution we come up with, some things to consider:

- The applied declarations may span multiple rules
- The actual value of the property may only be used in conditionals (e.g. `--size: [small | medium | large]`) or it may be used directly in some values, and *also* in conditionals.

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


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

Received on Thursday, 15 October 2020 16:02:38 UTC