Search code examples
javascripthtmlcssreactjsshadow-dom

Modify CSS inside a Shadow DOM


I have a shadow DOM being created by a third party. I want to set the display of a div with class .controls inside the shadow DOM to none. How can I achieve this via CSS?

<div class="documentation__design">
  <figspec-file-viewer>
    #shadow-root (open)
      <div class="controls">
        <select></select>
      </div>
      <div class="view"></div>
  </figspec-file-viewer>
</div>

Solution

  • You have to directly reach into the shadowRoot, get the.controls element and set the inline style

    document
       .querySelector("figspec-file-viewer")
       .shadowRoot
       .querySelector(".controls")
       .style
       .display = "none";
    

    or append a <style> tag to the shadowRoot:

    document
       .querySelector("figspec-file-viewer")
       .shadowRoot
       .append(
          Object.assign( document.createElement("STYLE") ,
                         {
                           innerHTML : `.controls {
                                           display : "none";
                                         }`
                         }
                        )// Object.assign
              )// append
    

    As mentioned in the comments a part could do. With the above mentioned method you can set a part attribute on any DOM element inside shadowDOM, and then use global CSS(*) to style it.

    (*) Strictly speaking not global CSS but CSS in the container where the shadowRoot was created in. Thus with 3 levels of shadowRoot, set the :part CSS in the 2nd shadowRoot.

    or to pass nested part definitions to its parent container see the exportparts attribute.

    https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/exportparts

    Ofcourse all this magic can only be done on open shadowRoots!

    super().attachShadow({mode:"open"})