w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.46k stars 657 forks source link

[css-shadow-parts] Should `::part():lang()` and `::part():dir()` be valid? #9795

Open keithamus opened 8 months ago

keithamus commented 8 months ago

Context

When implementing CSS CustomStateSet (:state(x)) one of the test cases became using it after ::part(x) which seems very reasonable; there are many existing states which are allowable on ::part(x) such as :focus, :hover and so on so it stands to reason that custom states should also be allowed.

:state(x) highlighted something tricky though, because Stylo's parser special cases functional pseudo selectors, of which there are :dir(), :lang(), and now :state(). Stylo explicitly flags :part() so it can disallow :lang/:dir (see this code where after_part is checked). WebKit, on the other hand, does not discriminate functional pseudo selectors from their non-functional counterparts, and so ::part(x):lang(y) works and also handles all the proper invalidation. Chrome does not successfully parse these selectors either, but I can't speak for how Chrome's parser works in this regard, perhaps @josepharhar can.

When speaking with @emilio about this, I was encouraged to file this very spec issue (better late than never :wink:).

Given Safari already parses and properly invalidates :lang/:dir on ::part(), I thought I'd add some WPTs (parsing, invalidation of ::part():lang(), invalidation of ::part():dir(), cc @nt1m). We can clearly see Safari is the outlier in this regard, as Chrome nor Firefox parse the selectors.

Problem statement

The question becomes: should Safari disallow :lang()/:dir() after part? Or should Firefox & Chrome allow it?

emilio commented 8 months ago

So I tend to think we shouldn't allow these because they expose the language / direction of ancestors / descendants of the part, which feels a bit weird.

But that said I know the rules about :lang() / :dir() in shadow trees have been discussed quite a bit... cc @meyerweb @zcorpan @rniwa

nt1m commented 8 months ago

@tabatkins recently edited the parsing tests to assert that those are valid: https://github.com/web-platform-tests/wpt/pull/43796 . It does indeed seem to be what the spec says, I'm happy to settle with that.

emilio commented 8 months ago

I guess the question is "do we consider :dir() and :lang() to "reveal tree structure"? I think you could say they do... If so, they should never match, probably.

Given https://github.com/whatwg/html/pull/9880#issuecomment-1892568094 I'd much rather make them invalid for now and make a decision once all those HTML issues about how language and directionality work in the shadow DOM are settled.

nt1m commented 8 months ago

I don't mind either way tbh. One question if we do reject them is whether they should be unparsable altogether or just match nothing.

emilio commented 8 months ago

Unparsable works with supports and such, so that seems preferable.

css-meeting-bot commented 7 months ago

The CSS Working Group just discussed [css-shadow-parts] Should `::part():lang()` and `::part():dir()` be valid?, and agreed to the following:

The full IRC log of that discussion <fantasai> scribenick: fantasai
<fantasai> TabAtkins: Question is whether :lang() and :dir() should work on ::part pseudo-elements
<fantasai> TabAtkins: I think from specs they do, because ::part() allows all pseudo-classes to work except those that expose internal structure
<fantasai> TabAtkins: we want authors to be able to rearrange their shadow DOM with minimal disruption to authors
<fantasai> TabAtkins: The question was whether :lang()/:dir() expose structural information
<fantasai> TabAtkins: I believe the spirit of the restricitons aren't violated by these
<fantasai> TabAtkins: and use cases are reasonable to justify
<fantasai> emilio: could go either way, but it exposes potentially values of attributes in the shadow tree
<fantasai> emilio: could argue that you don't know where the info comes from
<fantasai> emilio: before discussing I had slight pref for not allowing, now could go either way
<TabAtkins> fantasai: with my i18n hat on
<dholbert> fantasai (IRC): with my i18n hat on
<TabAtkins> fantasai: i think if you're allowed to style these, you shoudl be allowed to use :lang() and :dir() to control that
<TabAtkins> fantasai: lots of styling that's lang or direction dependent, and if we're gonna allow it in the first place we shoudl allow it to be done proeprtly
<TabAtkins> fantasai: if you're exposing these parts, they'll probably contain things you've passed to the shadow, so you need to style them
<TabAtkins> emilio: lang and dir don't propagate to the stuff you've put in
<fantasai> fantasai: if you're allowing styling, you should allow selecting against lang/dir
<fantasai> TabAtkins: Are there objections to allowing :lang()/:dir() to match ::parts?
<fantasai> [tense silence]
<fantasai> TabAtkins: OK, then. I already have WPT for this
<fantasai> RESOLVED: :lang()/:dir() do apply to ::part