[csswg-drafts] [css-values-4][Editorial] `<boolean>` type that other specs reference (#10457)

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

== [css-values-4][Editorial] `<boolean>` type that other specs reference ==
This came up when I went to implement the resolution from #10064 and spec my `if()` proposal.

Currently, we have several specs using one or more types of conditionals, and in every case, this is defined inline. This means the boolean operators (`and`, `or`, `not`) are also defined inline, which is awkward, error-prone, and easy to forget.

Some examples:

[Media Queries 5](https://drafts.csswg.org/mediaqueries-5/#typedef-media-query-list):

```
<media-query> = <media-condition>
             | [ not | only ]? <media-type> [ and <media-condition-without-or> ]?
<media-type> = <ident>

<media-condition> = <media-not> | <media-in-parens> [ <media-and>* | <media-or>* ]
<media-condition-without-or> = <media-not> | <media-in-parens> <media-and>*
<media-not> = not <media-in-parens>
<media-and> = and <media-in-parens>
<media-or> = or <media-in-parens>
<media-in-parens> = ( <media-condition> ) | <media-feature> | <general-enclosed>
```

[`@supports`](https://drafts.csswg.org/css-conditional-3/#typedef-supports-condition):

```
<supports-condition> = not <supports-in-parens>
                     | <supports-in-parens> [ and <supports-in-parens> ]*
                     | <supports-in-parens> [ or <supports-in-parens> ]*
<supports-in-parens> = ( <supports-condition> ) | <supports-feature> | <general-enclosed>
<supports-feature> = <supports-decl>
<supports-decl> = ( <declaration> )
```

[CSS Conditional 4 adds…](https://drafts.csswg.org/css-conditional-4/#at-supports-ext):

```
<supports-feature> = <supports-selector-fn> | <supports-decl>
<supports-selector-fn> = selector( <complex-selector> )
```

[CSS Conditional 5 adds…](https://drafts.csswg.org/css-conditional/#at-supports-ext

```
<supports-feature> = <supports-selector-fn> | <supports-font-tech-fn>
                    | <supports-font-format-fn> | <supports-decl>
<supports-font-tech-fn> = font-tech( <font-tech> )
<supports-font-format-fn> = font-format( <font-format> )
```

[`@container`](https://drafts.csswg.org/css-contain-3/#typedef-container-condition):

```
<container-condition> = [ <container-name> ]? <container-query>
<container-name> = <custom-ident>
<container-query>     = not <query-in-parens>
                      | <query-in-parens> [ [ and <query-in-parens> ]* | [ or <query-in-parens> ]* ]
<query-in-parens>     = ( <container-query> )
                      | ( <size-feature> )
                      | style( <style-query> )
                      | <general-enclosed>

<style-query>         = not <style-in-parens>
                      | <style-in-parens> [ [ and <style-in-parens> ]* | [ or <style-in-parens> ]* ]
                      | <style-feature>
<style-in-parens>     = ( <style-query> )
                      | ( <style-feature> )
                      | <general-enclosed>
``` 

[`@import`](https://drafts.csswg.org/css-cascade-5/#at-import):

```
<import-conditions> = [ supports( [ <supports-condition> | <declaration> ] ) ]?
                     <media-query-list>?
```

[Tab’s `@when` proposal](https://drafts.csswg.org/css-conditional/#when-rule):

```
media() = media( [ <mf-plain> | <mf-boolean> | <mf-range> ] )
supports() = supports( <declaration> )
```

In fact, there is an inline issue right there proposing a lighter form of what I’m arguing for here:

> Define "boolean algebra, with X as leaves" in a generic way in Conditional, so all the conditional rules can reference it directly, rather than having to redefine boolean algebra on their own.

## Proposal

I propose we introduce a new `<boolean>` or `<condition>` value type that other specs can reference.
It will include both the grammar for the boolean algebra, as well as bare and functional forms for each conditional.
Each conditional type should also include metadata like:
- Can it change over the course 

Not all condition types need to be defined in values, we could extend the `<condition>` token in other specs, as we often do with value types. E.g. size queries may be a better fit in css-contain, since they are not valid anywhere else.

The prose should explain that specs using `<condition>` should specify:
1. Which types of conditions are allowed?
2. Which types of conditions can be specified bare, i.e. without a function name.

To make this more concrete, this is the state of the current specs with conditionals with this framing:

| Host | `supports()` | `media()` | `size()` | `style()` |
|-----|-------|-------|-------|-------|
| `@container` | - | - | - | ✅ Bare | ✅ |
| `@supports` | ✅ Bare | - | - | - |
| `@media`  | - | ✅ Bare | - | - |
| `@import`  | - | ✅ | ✅ Bare | - |
| `if()` | ✅ | ✅ | - | ✅ |
| `@if` / `@when` | ✅ | ✅ | - | ✅ |

While this change is editorial, I think it will pave the way for a lot of quick DX wins involving mixing and matching conditions (e.g. `supports()` in `@media`.

It could also allow creating JS APIs that handle conditions generically, avoiding the current issue of e.g. having `matchMedia()` for media queries, but no way to detect when a container query matches or not.

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


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

Received on Monday, 17 June 2024 20:42:11 UTC