Bug 232261 - :host::part(foo) selector does not select elements inside shadow roots
Summary: :host::part(foo) selector does not select elements inside shadow roots
Alias: None
Product: WebKit
Classification: Unclassified
Component: CSS (show other bugs)
Version: Safari Technology Preview
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Antti Koivisto
Keywords: InRadar
Depends on:
Blocks: 148695
  Show dependency treegraph
Reported: 2021-10-25 12:51 PDT by Nolan Lawson
Modified: 2021-11-04 19:18 PDT (History)
12 users (show)

See Also:

Patch (10.41 KB, patch)
2021-11-04 01:01 PDT, Antti Koivisto
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Nolan Lawson 2021-10-25 12:51:19 PDT
Using CSS like:

    ::part(foo) {
      color: blue;


    :host::part(foo) {
      color: blue;

...does not work inside of shadow roots to select CSS shadow parts.

Here are two examples to demonstrate:

- https://codepen.io/nolanlawson-the-selector/pen/GRjxEYZ
- https://codepen.io/nolanlawson-the-selector/pen/jOLBxad

These two examples work in Firefox v93 (i.e. the font color is blue), but not Safari Tech Preview 15.4 release 133.

Incidentally, Chrome also fails this test, and there is a Chrome bug already open: https://crbug.com/980506
Comment 1 Antti Koivisto 2021-10-29 23:12:54 PDT
The first one is clearly wrong, ::part should not match in the current scope. That it works in Firefox seems like a bug.

The second one doesn't work in any browser. It is unclear if it should work since :host is such a poorly defined special case.
Comment 2 Emilio Cobos Álvarez (:emilio) 2021-10-30 01:21:00 PDT
Yeah, so `:host::part()` works intentionally in Firefox (https://bugzilla.mozilla.org/show_bug.cgi?id=1624968). I think the fact that bare `::part()` matches in that scope is an accidental change introduced by that bug's changes, but should probably be considered a bug.
Comment 3 Antti Koivisto 2021-10-30 01:56:14 PDT
Ah right, :host::part does work in FF.
Comment 4 Nolan Lawson 2021-11-01 08:36:23 PDT
Thanks for the clarification. I can understand the case for having `:host::part(foo)` work, whereas `::part(foo)` shouldn't work. I suppose `::part(foo)` gets ambiguous if a component contains other components with the same part name.

From a web developer's perspective, I think having just `:host::part(foo)` is adequate – the main thing is to have some way to reference one's own parts from within a component. (Of course `[part="foo"]` also works, but it feels a bit hacky since it's the part that matters, not the attribute.)
Comment 5 Nolan Lawson 2021-11-01 08:37:49 PDT
Renamed the bug title to focus on `:host::part(foo)`, not `::part(foo)`.
Comment 6 Radar WebKit Bug Importer 2021-11-01 12:52:23 PDT
Comment 7 Antti Koivisto 2021-11-04 01:01:57 PDT
Created attachment 443283 [details]
Comment 8 Simon Fraser (smfr) 2021-11-04 08:51:04 PDT
Comment on attachment 443283 [details]

View in context: https://bugs.webkit.org/attachment.cgi?id=443283&action=review

> Source/WebCore/css/SelectorChecker.cpp:418
> +        MatchResult result = matchRecursively(checkingContext, nextContext, ignoreDynamicPseudo);

Comment 9 EWS 2021-11-04 09:15:21 PDT
Committed r285262 (243873@main): <https://commits.webkit.org/243873@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 443283 [details].
Comment 10 Nolan Lawson 2021-11-04 09:33:11 PDT
This is awesome! Thank you!!
Comment 11 Antti Koivisto 2021-11-04 09:53:04 PDT
Thanks for reporting!