[csswg-drafts] [css-pseudo] Can we make pseudo-elements first-class citizens in the DOM? (#11559)

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

== [css-pseudo] Can we make pseudo-elements first-class citizens in the DOM? ==
## Fun with Pseudos

In light of View Transitions I’ve been playing **a lot** with pseudo-elements trying to do all sorts of things with them from within JavaScript:

- Access them
- Get info about their position+size
- Animate them
- Get their animations
- Access their styles

Accessing the pseudos themselves is in theory possible through [`Element.pseudo()`](https://drafts.csswg.org/css-pseudo-4/#window-interface) but in practice it has no browser support[^1].

[^1]: Thankfully I didn’t really need the pseudos directly in my experiments. Because I only needed the animations+effects applied to them, I was able to [sniff them out through `document.getAnimations()`](https://www.bram.us/2025/01/01/view-transitions-snippets-getting-all-animations-linked-to-a-view-transition/)

Some of the other features I listed above are made possible in some APIs through means of the `pseudoElement` option. When working with these it becomes quickly pretty clear that this `pseudoElement` is an afterthought that was introduced in order to get it to work quickly, instead of fully adopting the existence of [`CSSPseudoElement`](https://drafts.csswg.org/css-pseudo-4/#CSSPseudoElement-interface). See https://github.com/w3c/csswg-drafts/issues/4301 for example that chose to add the `pseudoElement` option to `Element.animate` instead of embracing `CSSPseudoElement`.

Since then other APIs have also been monkey-patched to accept a `pseudoElement` option:
- `getComputedStyle` in ???
- `Element.getAnimations()` in https://github.com/w3c/csswg-drafts/issues/9908#issuecomment-2165621635

So as for the things I want to do with pseudos this is the current state of affairs:

- Access them: Theoretically using `pseudo()` but that has not shipped anywhere.
- Get info about their position+size: Not directly possible _(you could anchor a real Element to it and then do getBCR on that Element)_.
- Animate them: Only if they already have animation attached to them that you can hijack
- Get their animations: Theoretically using `Element.getAnimations()` but that is not specced yet. You can sniff ’m manually, though.
- Access their styles: `getComputedStyle()` with `pseudoElt` param.

<mark>With more and more features leaning on pseudo-elements (select::picker, ::details-content, carousel pseudos, customizable select, etc.) this problem will become more visible to authors.</mark>

## Making pseudo-elements first-class citizens

Instead of monkey-patching more APIs to accept a `pseudoElement`, I believe it would be nicer if pseudo-elements becamse first-class citizens of the DOM. All the pieces of the puzzle are there, it’s a matter of putting them together:

- Access them:
  - Already specced: [`pseudo()`](https://drafts.csswg.org/css-pseudo-4/#window-interface) which returns a [`CSSPseudoElement`](https://drafts.csswg.org/css-pseudo-4/#csspseudoelement)
- Get info about their position+size: 
  - Add (only some?) of [these extensions to `Element` from cssom-view](https://drafts.csswg.org/cssom-view/#extension-to-the-element-interface) also to `CSSPseudoElement`
  - If not all, then at least these would be needed:
    ```js
    partial interface CSSPseudoElement {
      DOMRectList getClientRects();
      [NewObject] DOMRect getBoundingClientRect();
    }
    ```
  - For reference: The `CSSPseudoElement` is [already defined to include the `GeometryUtils` mixin](https://drafts.csswg.org/cssom-view/#the-geometryutils-interface).
- Animate them:
  - Have `CSSPseudoElement` include [the `Animatable` mixin](https://drafts.csswg.org/web-animations-1/#the-animatable-interface-mixin), [similar to `Element`](https://drafts.csswg.org/web-animations-1/#extensions-to-the-element-interface).
    ```js
    CSSPseudoElement includes Animatable;
    ```
- Get their animations:
  - Tackled by the `Animatable` mixin from the previous point.
  - Also: undo the resolution from https://github.com/w3c/csswg-drafts/issues/9908#issuecomment-2165621635 and remove the `pseudoElement` option from `getAnimations()` _(which is safe to do because this is not specced + has not shipped anywhere)_
- Access their styles:
  - In addition to `getComputedStyle()` with `pseudoElt` param, have [`getComputedStyle`](https://drafts.csswg.org/cssom/#extensions-to-the-window-interface) also accept a `CSSPseudoElement` as its first argument.
    - This would also make a nicer solution to https://github.com/w3c/csswg-drafts/issues/4456

## Just a starting point

Most likely I’m overlooking a bunch of things and I’m definitely lacking some nuances to some of the many pseudos that would allow/disallow this – so I’m very much looking forward to input on this one.

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


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

Received on Wednesday, 22 January 2025 22:23:25 UTC