[csswg-drafts] [css-conditional] Custom `@if` conditions via JavaScript (#9782)

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

== [css-conditional] Custom `@if` conditions via JavaScript ==
In #3559 we were searching for a way to check for contextual support of features like `gap` in Flexbox, `align-content` in Block layout and similar things.

At some point in the discussion I then came up with the idea to solve this via of [script-based custom `@supports` rules](https://github.com/w3c/csswg-drafts/issues/3559#issuecomment-1114545949). I also provided [an example](https://github.com/w3c/csswg-drafts/issues/3559#issuecomment-1155066354) for how those could be used to check whether `gap` is working in the context of a Flex layout.
@fantasai then [pointed out in a call](https://github.com/w3c/csswg-drafts/issues/3559#issuecomment-1249795176) that those conditional checks can be thought broader and might be added to the [`@when`](https://drafts.csswg.org/css-conditional-5/#when-rule) (she said `@if` back then) instead.

The concept behind that is to allow to register a named condition worklet, which can then be used as condition in `@when` rules. Its way of working would be similar to other worklets like [Paint Worklets](https://drafts.css-houdini.org/css-paint-api/#paint-worklet).

This makes conditionally applying styles very versatile and covers a lot of use cases like the mentioned contextual feature check, [time- and date-based styling](https://github.com/w3c/csswg-drafts/issues/9710), allow to [apply styles based on scroll direction](https://github.com/w3c/csswg-drafts/issues/6400), or might even be a way to solve [layout-dependent styling](https://github.com/w3c/csswg-drafts/issues/5979).

The concrete proposal is to add a worklet that looks like this:

```js
class Condition {
    static get inputProperties() { return []; }
    static get inputArguments() { return []; }
    static get contextOptions() { return {once: true, currentDocument: false}; }

    check(document, styleMap) {
        // Do check
    }
}

registerCondition('--condition', Condition);
```

Where the context option `once: true` means the check is only executed a single time right after the rule is parsed. So it works like an `@supports` check. If it is set to false, the check is executed continuously like in different `@media` conditions.
Maybe instead of running continuously, some way to execute only once specific DOM properties change could be introduced. E.g. only execute once `document.location` changes.

The context option `currentDocument` indicates whether the `document` parameter of the `check()` method refers to the current page's document or is independent from it.
For some use cases like feature support checks you only need access to an independent DOM. Though in many use cases access to the current DOM is necessary.

Both of those options definitely require some deeper thought on performance, privacy, and security.

The worklet can then registered like that:

```js
CSS.conditionWorklet.addModule('condition.js');
```

And finally, in CSS you'll use it like this:

```css
@when --condition {}
```

Sebastian

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


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

Received on Wednesday, 10 January 2024 22:15:45 UTC