Search code examples
javascriptcssweb-componentshadow-dom

How to access light dom of custom element inside a slot?


So, basically I have a ui-button that is a molecule. This element is composed with ui-text and ui-icon elements that are atoms. I want apply a margin-left to the text when the button has an icon.

However, the text is a span element inside the shadow dom of ui-text. That means that inside ui-button I have a nested shadow dom corresponding to ui-text:

<ui-button kind="primary" useForClick="someFn">
  <ui-icon name="payment"></ui-icon>
  <ui-text>Pay with card</ui-text>
<ui-button>

Rendered:

ui-button
|__shadow dom
   |__ui-icon
   |__ui-text
      |__shadow dom
         |__span

How can I access to the inner shadow dom from parent element via CSS? The idea is apply something like this inside ui-button:

slot[name=text]::slotted(ui-text) span::slotted() {
  margin-left: 10px;
}

Solution

  • Ideally, you would use ::slotted( ui-icon + ui-text ) { margin-left: 10px } in the <ui-button> Shadow DOM in order to add a left margin to a <ui-text> element following a <ui-icon> element.

    Actually il not possible because ::slotted() allow only compound selector, not complex ones constructed with +, >, ~ and (space). You'll have to find a workaround depending on your need.

    In the example above you can use the :first-child pseudo-class combined with :not() pseudo-class function.

    ::slotted( :not(:first-child) ) {
        left-margin: 10px 
    }
    

    You can read also this related post for an alternate solution with :host().