-
Notifications
You must be signed in to change notification settings - Fork 747
Description
Description
According to the spec 3.2.4. Selecting Slot-Assigned Content: the ::slotted() pseudo-element:
The specificity of
::slotted()
is that of a pseudo-element, plus the specificity of its argument.
In a previous conversation (#1915 (comment)), it was clear and the solution proposed is to use !important
but I think that the current solution is a bad Developer Experience when you apply it to real life.
Following the definition,::slotted(h1)
should have a 0-0-2 specificity and h1
just 0-0-1. Then ::slotted(h1)
should win without !important
. But it seems they don't fight in the same arena and !important
is required.
Example
Here is an that explains better the use case. Taking this HTML as a base. We want to use slots to take the advantage of HTML declaration, for example for SEO reasons.
<fancy-hero>
<"shado-dom">
<style>
:host {
background: #333;
}
:slotted(h1) {
color: #CCC;
}
</style>
</"shado-dom">
<h1>My site is awesome</h1>
</fancy-hero>
We would like to have some generic styles for headings and paragraphs but the web component would like to restyle them using the ::slotted()
pseudo-element. As there are other h1 in other pages without fancy-hero
wrapper, we have some generic styles like this:
h1 {
color: #333;
}
Then the color of my fancy-hero h1
changed to #333
. The only way to preserve the fancy-hero h1
style from inside the fancy-hero
is by applying !important
:host {
background: #333;
}
::slotted(h1) {
color: #CCC !important;
}
But once you do that, it's impossible to change from outside, to make my component customizable. And the only way is to use custom properties like this:
:host {
background: #333;
}
::slotted(h1) {
color: var(--hero-title-color, #CCC) !important;
}
Then I can customize my fancy-hero
adding this styles into the global styles:
fancy-hero{
background: red;
--hero-title-color: white;
}
Extrapolating this use case to a complex component with multiple slots and much more properties, it's not viable. At this point we have two options:
- Use shadow DOM to encapsulate styles, but we lost the light DOM advantage.
- Set
!important
and declare custom properties in all styles properties of my component.
Proposal
I would like to propose that shadow DOM styles fight with the global styles in the same conditions. The cascade should be applied independently where the styles are defined.
Coming back to the specificity definition::slotted(h1)
should have a 0-1-1 and h1
0-1-0. Then ::slotted(h1)
should win without !important
. This allows developers to create custom elements more reusable and easy to customize without dealing with thousand of custom properties and fill the code with !important
in all properties.
Demo
https://webcomponents.dev/edit/eQFJPlOvQMIuUZj71ohV/README.md
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Status