-
Notifications
You must be signed in to change notification settings - Fork 715
[specificity] Specifity of ::slotted() is greater than :host #2290
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
Comments
Unless I'm missing something this is working as expected. The children would only be red because of inheritance, but there's a rule specifying its color to green. |
i.e., this doesn't have to do anything with specificity at all. |
Yes, this particular issue is purely a result of the way the cascade handles inheritance vs direct application; it has nothing to do with specificity at all, since there aren't any clashing rules. |
Sorry it's not clear from the replies, is it an issue or not? If it's not specificity, is it just a downfall of the "direct application" you mention? If it were standard html and css it would be red wouldn't it? <style>
.host1 * {
color: green;
}
.host2 {
color: red;
}
</style>
<div class="host1">
<div>green</div>
<div class="host2">red</div>
</div> This undesired behaviour causes a lot of problems when designing composable elements as the nested custom element has no way of overriding the rules governed by the parent custom element (unless there is a technique I don't know about?). |
In your original example, the green and the red aren't being specified on the same element, so there's no specificity issue. Instead, you're setting the color on :host and relying on inheritance to propagate that downwards, but inheritance always loses to directly styling an element (which In your latest example, the two declarations are specifying the same property on a single element - "color: green" is being specified on the host2 element via the |
Are they not being specified on the same element?
targets the same element that
does?
The child element is the slotted element of the parent. Perhaps it's confusing things because I am using an example property which is inherited? This would still be an issue if it was using |
Oh, I see what you mean. host rules are indeed applied before slotted rules indeed, even though !important rules are applied in the reverse order (except in FF where we still don't implement that last bit, though we don't ship Shadow DOM). |
It's still not about specificity itself though. |
Ok it might not be about specificity, but to a layman I have no other way of describing it. How do we take this further? Is it a spec issue or a technical issue? |
Oh! I didn't realize there was a parent/child relationship going on here, I gotcha now. I should read more. (Cases like this are often confusing to explain; it helps to provide a markup example with shadow trees drawn in.) (Yeah, it's technically not specificity, but that's close enough to work. Technically it's the "Shadow Tree" cascade step; specificity is another cascade step.) So yeah, the So yeah, the element ends up green, and that's intended behavior. In general, styling of the host element is a coordination between the shadow tree and the outside page. <style>
.foo { color: green; }
</style>
<x-foo class=foo>
<::shadow>
<style>
:host { color: red; }
</style>
</::shadow>
</x-foo> In this case, the element ends up with |
I did provide a jsbin example but perhaps I should have been more explicit in my explanation. Thanks very much for taking the time to explain that. I won't pretend to understand it all but I get the gist of it. I don't agree with the approach of using Coming from conventional html and css and my inferior experience with custom elements and the shadow dom, it doesn't seem natural to me, but I appreciate I'm probably not smart enough to understand the reasons why. The best method I can find is to use a custom css property. This allows me to let nested custom elements override styles from outside but still allow me override the styling of the component should I need to. It might be useful to someone else in my situation although I feel one shouldn't have to do this because it can complicate things depending on your project.
|
Yeah, it also seems a bit unnatural to me the implications this has for the <!doctype html>
<div id="host" style="color: purple !important"></div>
<script>
host.attachShadow({ mode: "open" }).innerHTML = `
<style>:host { color: blue !important; }</style>
`;
</script> But I guess it's ok, I guess I can see cases where shadow trees really don't want their styles overriden by anything. |
I think I understand it a bit better now. I hadn't realised that the same occurs when you have an example like the following: <style>
h1 {
color: green;
}
</style>
<app-container>
<::shadow>
<style>
::slotted(*) { color: red; }
</style>
</::shadow>
</app-container> The output will be a green h1. It does make sense but it means that the only way for the custom element to change the colour the h1 is to use There needs to be a way of achieving the same as below but without having to apply the styles outside the custom element. <style>
* {
color: green;
}
app-container {
color: red;
}
</style>
<!-- ... -->
<app-container>
text will be red
</app-container> |
A few reasons went into the current design:
|
Thanks for explaining. |
Based on feedback from w3c/csswg-drafts#2290 (comment)
Based on feedback from w3c/csswg-drafts#2290 (comment)
If you declare styles inside a component which use the
:slotted()
selector then styles applied by any child components which are uses inside that component cannot be overridden using:host
.I would expect the child custom element's text to be red, but it is in fact green.
http://jsbin.com/cecuxad/edit?html,console,output
Is there anything in the spec that covers this behaviour?
The text was updated successfully, but these errors were encountered: