-
Notifications
You must be signed in to change notification settings - Fork 658
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[css-scoping-1] Clarify exactly what :host(<sel>) can use as argument #7953
Comments
My naive preference is to say the answer to 1 is "yes, and yes" (allow smuggling in complex selectors, and just loosen the grammar to allow them generally), and to 2 is also "yes" (allow the selectors to see the host's light dom surroundings). But the restrictions were originally put in place for perf reasons, and I'm not involved with the implementation, so I can't say how problematic this would be. |
Same as #6737? |
Ah yes, question 1 is a dupe of #6737, but question 2 is still distinct. Thanks for the ref! |
For consistency, if restrictions are lifted on :host(), restrictions should also be lifted for ::slotted()? There is some bug with :has() in ::slotted() in Safari (lime bg on the span without an <i> as well): <!doctype html>
<main>
<div id="host"><span>Green<span> <span>Green on lime<i></i></span></div>
</main>
<script>
let root = host.attachShadow({mode:"open"});
root.innerHTML = `
<slot></slot>
<style>
:host(:is(main > #host)) { background-color: blue; }
:host(:has(i)) { border: 10px solid orange; }
::slotted(span:has(i)) { background-color: lime; }
::slotted(:is(#host > span)) { color: green; }
</style>
`;
</script> |
I think I'd be opposed to lift the |
Yeah, that's a consistent position that I'm fine with, and suspected we'd land on. Just requires some extra work on the spec side to make it work. (Also, the original scenario that brought this up - that Reddit wants to know if there's anything assigned to a slot - would be solved both simpler and more correctly by #6867, so we can discount it as a motivating case.) |
Gonna close this as a dupe of #5093, where we have proposed edits answering this exact question - the logical combo pseudos pass their own context's restrictions on to their arguments. This means that |
@tabatkins I would like to see this issue reopened separately from #5093 There are some cases that are difficult to do without |
Is the case you're discussing "check if a If it's something else, could you elaborate? |
They're related, but not exactly the same. Consider a case like: :host(:not(:has(input:checked))) {
border: solid 4px red;
} meant to be used with markup like: <my-element>
<section>
<label>One: <input type="checkbox" name="one"></label>
<label>Two: <input type="checkbox" name="two"></label>
<label>Three: <input type="checkbox" name="three"></label>
</section
</my-element>
|
I am sorry to disrupt your current discussion. If I correctly understand the reason for restricting
Basically, any functional pseudo-class/element taking a selector as its argument should be restricted to I guess these cases cannot match anything? Should they be invalid?
And |
I'm agree with @justinfagnani here that |
The second and third are indeed invalid, but the first is valid. (It won't match anything, since the host element only matches
As both argument contain pseudo-elements, neither of them are compound selectors, so they're both invalid.
Yes. |
The :host() definition says:
This allows you to do things like
:host(.foo)
to test if the host element has thefoo
class, which you can't tell from within the shadow because the host is featureless.The selector argument is specified to only be a compound selector, with the intention that it only needs to look at the host element itself to match. (This was intentional and is the difference between it and
:host-context()
.) But technically selectors like:is(.foo .bar)
and:has(> .foo)
are also compound selectors, tho they contain complex selector arguments. Per the grammar they're allowed, but should they be? If they should be, should we just drop the<compound-selector>
restriction and go with a plain<selector>
? (This is a pretty general question for<compound-selector>
arguments in other locations, too.)Further, the intention of
:host()
when I wrote it was just to "de-cloak" the host element, but to do so I phrased the selector as matching "in [the host element's] normal context". This can be read as implying that:host(:has(> .foo))
tests if the host element has a light dom child with thefoo
class, and in fact Safari does exactly this, while Chrome doesn't. (Compare with:host:has(> .foo)
, which definitely tests if a shadow dom child has afoo
class.) Should this be considered correct?(Context: Reddit is apparently depending on the Safari behavior to style a
slot
element differently based on whether something is slotted into it or not, using a selector like:host(:has(> [slot="foo"]) slot[name="foo"]
. Without this behavior they'd have to listen for slotchange events and manually toggle a class on theslot
element.)So in short:
<compound-selector>
argument allow complex selectors to be "smuggled in" via:is()
and:has()
? If so, should we just drop the restriction entirely?:host()
literally evaluate its selector argument in the host tree, so its light-dom ancestors/descendants are visible to:host(:is(...))
and:host(:has(...))
?The text was updated successfully, but these errors were encountered: