2

I'm using the follow web-component tree:

<x-typography>
  :shadow-root
    <x-select>
      :shadow-root
        <div class="select-container>
        </div>
    </x-select>
</x-typography>

And I need to override the background-color on select-container. I don't have access to <x-select> code, only <x-typography>.

I know how to :host and ::slotted works, I tried:

:host(x-typography):host(x-select) .select-container
:host(x-typography):host(x-select) .select-container
:host(x-typography :host(x-select)) .select-container

But none of them work.

mkrieger1
  • 19,194
  • 5
  • 54
  • 65

1 Answers1

1

You can use the ::part pseudo-element and exportparts attribute for this. It allows you to make custom styles for inner Shadow DOM element.

You can specify a "styleable" part on any element in your shadow tree:

<x-select>
  :shadow-root
    <header class="select-header"></header>
    <div class="select-container" part="container"></div>
</x-select>

And then you can specify custom styles for that part like:

x-select::part(container){
  font-weight: bold;
}

Also it works with other pseudo selectors like :hover, :active...

x-select::part(container):hover {
  opacity: 0.8;
}

But it doesn't work with nested parts. So, you cannot use it like:

x-select::part(container)::part(aside) {
}

For that purpose you need to export the part via exportpart attribute.

<x-bar>
  :shadow-root
  <x-foo exportparts="some-box: foo-some-box"></x-foo>
</x-bar>

However, if you need to support IE11 then it might be not the best option. From the other hand, it's supported by all modern browsers: https://caniuse.com/#search=%3A%3Apart

So, your example would look like:

// x-select


render () {
  return (
    <Host>
      <div class="select-container" part="container"></div>
    </Host>
  )
}
// x-typography


render () {
  return (
    <Host>
      <x-select exportparts="container: container"></x-select>
    </Host>
  )
}
  
<!-- usage -->

<x-typography></x-typography>

<style>
  x-typography::part(container) {
    color: blue;
  }
</style>

Here you can find a great explanation how part works: https://github.com/fergald/docs/blob/master/explainers/css-shadow-parts-1.md

Ivan Burnaev
  • 2,690
  • 18
  • 27
  • Hi @ivan! It works but, just for record, I preferred to create some variables called *tokens* which I used to access and manipulate some style aspects, it's a common practice in design systems and was a better solution in my scenario. Thanks a lot! – Marcello Oliveira Oct 02 '20 at 19:28
  • You are absolutely right! My former colleague has written a great article about Design Tokens: https://medium.com/@didoo/how-to-manage-your-design-tokens-with-style-dictionary-98c795b938aa – Ivan Burnaev Oct 04 '20 at 11:53