Search code examples
cssangularweb-componentshadow-domangular-elements

Use CSS selectors like :first-child inside shadow dom


Is there any way to use css selectors like :first-child, :not(:last-child) inside of the shadow dom?

The example is like this

CustomElement.html

<div id="parent-div>
 <slot></slot>
</div>

App.html

<div>
 <custom-element>
   <div class="heading">Main Heading</div>
   <div class="item">item 1</div>
   <div class="item">item 1</div>
   <div class="item">item 1</div>
   <div class="heading">Second Heading</div>
   <div class="item">item 1</div>
   <div class="item">item 1</div>
   <div class="item">item 1</div>
 </custom-element>
</div>

what i want to do is find out the first .heading element and add custom styles to it. Since <div class=heading"> is actually a component, i can't add custom styling to it thinking only as the first heading.

P.S.:- I'm using angular-elements, if it helps


Solution

  • I found a workaround for this in JS way.

    For each slot, we have a eventHandler called (slotchange). By using that we can get the DOM event for the slot whenever the slot changes. Like this (HTML)

    <custom-element (slotchange)="onSlotChanged($event)"></custom-element>
    

    JS

    onSlotChanged($event) {
     console.log($event) // Go and research yourself about this event, you'll find many things usefull.
     $event.target.assignedNodes() // This will give you the array of every elements, that are in side of the shadow dom
     // Example usage, adding the margin-bottom to only first time (css :firsh-child)
     $event.target.assignedNodes()[0].shadowRoot.getElementById('some-id').style.marginBottom = '10px'
    }
    

    If you only need to add a property to the element, you don't have to query shadowDom like "node.shadowRoot". But, if you want to access the element inside the shadowRoot of that element, you have to use that