Style children of shadow dom ::part element
Asked Answered
C

1

8

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!

Castera answered 11/6, 2021 at 16:53 Comment(0)
C
6

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:

<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>
Comines answered 12/6, 2021 at 7:32 Comment(3)
Perhaps overlooked in this answer: it can be done by adding the part attribute to the subheader span: <span part="subheader"></span>Perspiratory
Is there any way to style a ::part(element) that :is(something)?Remorse
I don't think soPontiac

© 2022 - 2024 — McMap. All rights reserved.