Reputation: 2548
I have a web component that renders the following in the shadow dom:
<custom-banner>
#shadow-root
<div part="headertext">
I am the header text!
</div>
...
</custom-banner>
To style the headertext
, the following css works great:
custom-banner::part(headertext) {
border: 5px solid green;
}
Now say I have something like this:
<custom-banner>
#shadow-root
<div part="headertext">
I am the header text!
<span>I am the subheader text!</span>
</div>
...
</custom-banner>
Is there a way to target the children of a shadow part? That is, something like this (which doesn't seem to work):
custom-banner::part(headertext) span {
border: 5px solid red;
}
I realize that this sort of thing might undercut the whole purpose of ::part
, but maybe not?
To be clear, the subheader span is not a slotted child in this example. It is always part of the component and it is in the shadow dom. The examples above are meant to be the rendered component, in browser.
Thanks!
Upvotes: 8
Views: 8571
Reputation: 21143
Alas, you can only style the ::part
Node itself.
Not children, that would defeat the ::part
purpose,
might as well allow all shadowDOM styling from the outside then. (can't be done)
The exportparts attribute can pass part
definitions to parent Nodes
As mentioned in the comment;
You can specify a <span part="subheader">
,
OR you could use a CSS property, scoped to the part, see --subheader: blue
It all depends how much and which control you want to give to the user of your component.
good blogs:
::parts
by Monica Dinculescu (Google): https://meowni.ca/posts/part-theme-explainer/<style>
body {
/* note how 'inheritable styles' do style shadowDOM */
font: 28px Arial;
color: green;
}
custom-banner::part(headertext) {
/* style shadowDOM from global CSS */
background: pink;
--subheader: blue;
}
</style>
<custom-banner></custom-banner>
<script>
customElements.define("custom-banner", class extends HTMLElement {
constructor() {
super()
.attachShadow({mode:"open"})
.innerHTML = `<style> span { color:var(--subheader) } </style>` +
`<div part="headertext">I am the header text!` +
`<span>I am the subheader text!</span>` +
`</div>`;
}
});
</script>
Upvotes: 6