Home > Software design >  Use :root in Shadow DOM
Use :root in Shadow DOM

Time:09-12

  • I have been working on Shadow DOM and then I meet a problem.
  • I use the :root {} syntax to declare some CSS variables . But unfortunately, it does not work.
  • Here is my code
  • On 1.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8" />
      <meta http-equiv="X-UA-Compatible" content="IE=edge" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>Shadow DOM</title>
    </head>
    <body>
      <square-element></square-element>
      <script src="./1.js"></script>
    </body>
    
  • On 1.js:

    const htmlCode = `
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8" />
      <meta http-equiv="X-UA-Compatible" content="IE=edge" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>HTML Shadow DOM</title>
      <style>
        * {
          box-sizing: border-box;
          margin: 0;
          padding: 24px;
        }
    
        :root {
          --bg-color: cornflowerblue;
        }
    
        body {
          width: 100%;
          height: 100vh;
          background-color: antiquewhite;
        }
    
        .square {
          width: 500px;
          height: 500px;
          border: 5px solid #000;
          background-color: var(--bg-color);
        }
      </style>
    </head>
    <body>
      <div ></div>
    </body>
    </html>`;
    
    customElements.define(
    "square-element",
    class extends HTMLElement {
      connectedCallback() {
        const shadow = this.attachShadow({ mode: "open" });
    
        shadow.innerHTML = htmlCode;
      }
    });
    
  • Can I use CSS :root {} to decalre some varibales in Shadow DOM?

CodePudding user response:

  • shadowDOM is a DocumentFragment
    Unlike IFRAMEs, you can't dump a whole <html> construct in there

  • :root is to be used in Documents

  • :host is used from inside a shadowRoot, to target the host element <square-element>

  • :host/<square-element> itself is a (inline-block) container element;
    no need to add an extra <div> inside as 'container' element

<square-element>1</square-element>
<square-element selected>2</square-element>
<square-element color="purple">3</square-element>

<style>
  :root {
    --border-color: grey;
  }
</style>

<script>
  customElements.define( "square-element", class extends HTMLElement {
      constructor() {
        super().attachShadow({mode:"open"}).innerHTML = 
        `<style>
          :host {
            --bg-color: ${this.getAttribute("color") || "teal"}; 
            display:inline-block;
            width:  100px; 
            height: 100px;
            border: 5px solid var( --border-color , red  );
            background-color: var( --bg-color     , pink );
            border-radius: var(--radius,20px);
            font:30px Arial;
            text-align:center;
            color:beige;
          }
          :host([selected]) { --bg-color: green }
          :host([color])    { --radius: 50px }
          :host(:hover)     { --border-color: gold; cursor: grab }
        </style><slot></slot>`;
      }
    });
</script>

  • Related