Skip to content

[css-shadow-parts] Make ::slotted() a combinator #7922

@LeaVerou

Description

@LeaVerou

Currently ::slotted() is a functional pseudo-element, which causes no end of problems:

  1. No way to get slotted elements with querySelector() or any of the other DOM APIs that take selectors (querySelectorAll(), closest(), `matches(), etc)
  2. No ability to target descendants (see also)
  3. No ability to target siblings
  4. No ability to target pseudo-elements
  5. No way to detect slots that have content (with a combinator this is simply :has(/slotted/ *)
  6. No specificity for styling (making it a combinator won't outright solve this, but gives us a way around the web compat issues)

The intended way of going from one element to another based on their relationship in the DOM is combinators. That's why combinators exist. Even introducing a combinator that is just as restricted in syntax as the pseudo-element (minus the restrictions that are inherent to it being a pseudo-element) fixes many of these problems, and paves the way for relaxing the restrictions even further down the line.

Sure, it is a wart to have a combinator with a restricted syntax, but it's only one wart (and possibly even a temporary one) which allows us to solve numerous others.

Sure, all of these can be special-cased for ::slotted(), but that adds cognitive overhead for authors and complicates implementations in a way that is (a) perpetual (special casing needs to persist forever) and (b) unbounded — these special cases will only keep increasing.

Yes, we can't get rid of ::slotted() for the foreseeable future, even if we add this, but at least we can stop special casing stuff around it, and just direct authors to /slotted/. And who knows, maybe even down the line usage could drop below the axing threshold.

Other notes:

  • Making it a pseudo-class is not an option, as discussed in [scoping] Consider making :slotted(...) a pseudo class #7305 . However, unless @fantasai and I are missing something, it should be possible to make it a combinator (/slotted/), which would address all of the above.
  • ::part() has similar issues, but is not equally trivial to turn into a combinator because that would give the outside world access to too much of the shadow subtree, but ::slotted() refers to the light DOM so doesn't have these problems.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Friday Afternoon

    Status

    Wednesday afternoon

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions