2
votes

As far as I know, the /deep selector is deprecated to select shadow dom children. So I'm looking for another solution.

CSS scoping looks to provide solutions for ascending selector, but not for descending one.

Given this dom :

<script>
    $('.child').addClass('reached');
</script>
<div id="parent">
    #shadow-root
        <div class="child"></div>
    /shadow-root
</div>

How can I write the selector in the script to reach the .child element ?

Thank you for your help

1
Do you mean something like :slotted? If so, check out stackoverflow.com/questions/27622605/… Also start reading at w3.org/TR/dom41/#shadow-tree-slots and w3.org/TR/css-scoping-1/#selectors-data-modelTylerH
May be am I wrong, but I didn't success to use ::slotted to reach descending nodeshadf
jQuery was never designed to use shadow DOM. It is best to avoid it when working with Web components and shadow DOM. Use the native APIs like querySelector and querySelectorAll. They will save you lots of confusion and difficulty.Intervalia
Ok, so do you suggest a solution with querySelector ?hadf
A single querySelector can not penetrate shadowDOM. Instead you need to get to the component with one querySelector and then use a second querySelector on the shadowRoot of the element.Intervalia

1 Answers

4
votes

How can I write the selector in the script to reach the .child element?

To reach an element in the Shadow DOM, you should use the shadowRoot property on the element.

var parent = document.querySelector( '#parent' )
var child = parent.shadowRoot.querySelector( '#child' )
child.classList.add( 'reached' )

Note : the Shadow DOM must have been created in the open mode.

var sh = parent.attachShadow( { mode: 'open' } )

var parent = document.querySelector( '#parent' )
var sh = parent.attachShadow( { mode: 'open' } )
sh.innerHTML = `<style>
                    div.reached { color: green }
                </style>
                <div id="child">Child</div>
                `
var child = parent.shadowRoot.querySelector( '#child' )
child.classList.add( 'reached' )
<div id="parent">
</div>

Note: ::slotted is needed only if you have elements in the light DOM revealed with <slot>.


Is there alternative to /deep selector?

Short answer is no. Since Shadow DOM is aimed at isolating Shadom DOM from the main page, /deep was kind of an heresy.

A very new proposal, with ::part and ::theme pseudo-elements could give some control back, but it's not to be implemented soon.

Until then the main workaround is to use CSS custom properties.

However the 2 solutions must be implemented by the Web Component designer and cannot be overrided otherwise.