[csswg-drafts] [selectors-4] A :state() pseudo-class selector and state() function (#6556)

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

== [selectors-4] A :state() pseudo-class selector and state() function ==
Currently, there are a number of Pseudo-class selectors which are targetted at certain UI elements, although there are many more elements which carry a state which could be used to control presentation. A notable example is the `<dialog>` HTML element, which according to the [HTML spec](https://html.spec.whatwg.org/multipage/rendering.html#flow-content-3:the-dialog-element), UAs are expected to present a different style based on that state.

Other such states could include the scroll position, the loading state of an image, the seek time of a video, and others. Rather than add every possible state psuedo-class imaginable, I suggest we freeze the list of state-drive pseudo-class, and introduce the `:state()` pseudo-class, and the accompanying state() function to access that state.

### The Psuedo-class — `:state()`

The definition of the `:state()` pseduo-class would be as follows:

```
:state() = :state( <state-name> | <state-compare> )
state-compare= <state-name> [ "=" | [ ">" | "<" ] "="? ] <state-value>
```

Using only the state name is equivalent to a boolean check, so `dialog:state(modal)` will only match if the "modal" state of `<dialog>` is set to "true". (For other states, the UA may decide if certain non-boolean values are "truthy")

Meanwhile, if you want an image to be only displayed after it is at least 50% loaded, then you might use:

```CSS
img:state(progress < 50%) {
  display: none;
}
```

Of course, you could also select pseudo-classes with their own dedicated selector, such as `:state(visited)`, although dunno why you'd wanna do that. Would be much more interesting for "custom elements", replacing the [--* prefixed pseudo-class](https://wicg.github.io/custom-state-pseudo-class/) that Chrome recently added, as it doesn't have a good way to represent states that aren't only a boolean.

### The function — `state()`

Although a state pseudo-class has been discussed before, and has a (in my opinion incomplete) implementation, I haven't seen anyone suggest a function to call it within CSS. This would allow us to "do something" with the state's value, beyond checking what it is. This would work like `attr()`, where you can assign the state's value to a property with a unit type, and an optional fallback.

```CSS
/* Display a red bar that displays the current position in the video via its width. */
video::after {
  display: block;
  background-color: red;
  height: 1em;
  width: calc(0% + state(seek) / state(duration) ) ;
}
```

Usability for the function might be somewhat limited outside of custom elements, as there's no way to propagate a state value upwards (such as in the above example, it would be preferable if one could pass a variable to a parent container, and rendering the status bar in one of the video's siblings), whereas many elements that might hold a state don't have any children (Or as with `<video>`, all its children are hidden/replaced). Still, it would compliment custom states in the host scripting language, as it would allow styling the Document according to a state's value, without actually manipulating the DOM. (usually done by applying/removing classes, or modifying a `style` attribute)

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


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

Received on Sunday, 29 August 2021 06:05:31 UTC