crowhill
crowhill

Reputation: 2548

Style children of shadow dom ::part element

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

Answers (1)

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>

Upvotes: 6

Related Questions