top of page

Scoping CSS using Shadow DOM

Shadow DOM is part of the DOM, which is capable of isolating JavaScript and CSS. If you have heard of iframes, Shadow DOM is also something that has similar capabilities.

Just like in iframes, by default, styles within a shadow DOM won’t leak out and styles outside ofit won’t leak in.

There are ways to inherit some styles from outside of the Shadow DOM too, if required.

ree

Structure of a Shadow DOM


CSS libraries like Styled-components also solve the name collision issue by generating a random class name like .kjkgh2en3. However, Shadow DOM offers style encapsulation by design! Next, let’s have a look at how to add a shadow DOM.

Can we use it in Any Project?

Although modern browsers support Web Component Specification, there are some challenges if we try to use it for existing applications.

It’s more like standardizing the Component Definitions native to browsers, where you can create new elements as we do with React, Angular &, etc.

Therefore, it’s essential to check out the feasibility of adopting Shadow DOM, depending on the component libraries you use.

Adding a Shadow DOM

There are two ways to add a shadow DOM.

  1. Open mode

  2. Closed mode


Open mode

class MyComponentOpenRoot extends HTMLElement {
   constructor() {
      super();
      this.attachShadow({ mode: 'open' });
      this.close = this.close.bind(this);
   }
}

Attaching a shadow DOM with mode: 'open' saves a reference to the shadow root on element.shadowRoot. Therefore, we can access the shadow root via this reference.

Closed mode

Opposed to the open mode, the closed mode does not store a reference. We will have to create our own storage and retrieval way using either a Weak Map or an Object if we use the closed mode.


const shadowRoots = new WeakMap();class MyComponentClosedRoot extends HTMLElement {
   constructor() {
     super();
     const shadowRoot = this.attachShadow({ mode: 'closed' });
     shadowRoots.set(this, shadowRoot);
   }   connectedCallback() {
     const shadowRoot = shadowRoots.get(this);
     shadowRoot.innerHTML = `<h1>Hello!</h1>`;
   }
}

Now that we have created a Shadow DOM, let’s look at how to attach and apply styles to the Shadow DOM nodes.

We will be using the open mode here onwards.

Attaching styles in the Shadow DOM

class MyComponentOpenRoot extends HTMLElement {  
  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
    this.close = this.close.bind(this);
  }
 
  connectedCallback() {
    const { shadowRoot } = this;
    shadowRoot.innerHTML = `<style>
      .wrapper {
        opacity: 0;
        transition: visibility 0s, opacity 0.25s ease-in;
      }

      .overlay {
        height: 100%;
        position: fixed;
        top: 0;
        right: 0;
      }

      button {
        cursor: pointer;
        font-size: 1.25rem;
      }
    </style>
    <div class="wrapper">
    <div class="overlay"></div>
      <div>
        <button class="close">✖️</button>
        <h1 id="title">Hello world</h1>
        <div id="content" class="content">
          <p>This is content outside of the shadow DOM</p>
        </div>
      </div>
    </div>`;
  }
}

All the styling required for the Shadow DOM nodes can be specified in the above manner. These styles will only apply to nodes inside the Shadow DOM as they are attached to the shadow root.

The Shadow DOM will be shown as below in the Chrome Dev Tools DOM elements.

ree

So far, Shadow DOM seems very appealing. Finally, we have a way to scope out CSS without any hacks!

Using Shadow DOM in Practice

  1. There are alternatives to Shadow DOM, such as styled-components. However, since styled-components have CSS in JS, it is less performant than Shadow DOM. But if you already have styled-components in your project, you can stick to it rather than moving to Shadow DOM for style encapsulation.

  2. Even though Shadow DOM provides some powerful tools, we should not use it always. For example, if you have an <form> element in your DOM, you shouldn’t use Shadow DOM for components inside the form, such as input or textarea. This is because you cannot query nodes inside the shadow tree from the outside. Therefore, the form will ignore the components where Shadow DOM is used.

  3. If you want to style your component using a global CSS stylesheet, you should avoid using Shadow DOM in that particular component, as the global styles will not be applied if you use it.

  4. You should handle event propagation with care if you are using Shadow DOM in your component, as the use of UI events is different in and out of the shadow boundary.

  5. If you are using many third-party plugins or integrations in your application, you should be aware that some of these may not work with components that have Shadow DOM as they are not built to deal with it.

  6. Shadow DOM supports <slot> elements where you can render components from the light DOM to your Shadow DOM positions. When <slot> is used, the browser performs composition and renders light DOM elements in corresponding slots in the Shadow DOM.

  7. There are more ways of declaring a Shadow DOM as well. For example, Declarative Shadow DOM, which brings the Shadow DOM to the server. This is an exciting area to explore if you are interested in learning more about the Shadow DOM.

  8. Encapsulated styling is essential when sharing components between different web projects using tools like Bit. A reusable component should be context-agnostic - which should include preventing any possible styling/naming conflicts in possible hosting environments. For example, the following styled component I have shared on Bit can be used in any project without worrying about style conflicts.


ree

Shadow DOM provides out-of-the-box style isolation and DOM encapsulation, perfect for self-contained, reusable components for your UIs.

Browser Compatibility

If your application needs to be run on Internet Explorer, Shadow DOM is not the way for you as it has no support for Internet Explorer. But the rest of the commonly used browsers comes with support for Shadow DOM.

ree

Source: MDN


Summary

If you are interested in productive and efficient frontend development without worrying about style class name collision, Shadow DOM is a great option. Whether to use Shadow DOM or use a CSS library such as styled-components to avoid name collisions is entirely up to you.




Source: Medium; Viduni Wickramarachchi


The Tech Platform

17 Comments


regiuietg
Sep 04

Shadow DOM is a clean way to get true style and DOM encapsulation—perfect for reusable, self-contained components. An AI logo maker makes it easy to craft designs that stand out. From bold metal logo creations and stylish black metal themes to energetic football graphics or refined high end branding, every detail can shine with realistic 3D effects or striking typography. Whether for your YouTube channel, a rising band, a cozy cafe, a fast food business, a sports team. competitive esports and gaming teams, or even an elegant wedding, you’ll find the perfect logo solution.

Like

Guest
Aug 06

Step into the world of free gaming downloads with SteamUnlocked.

Like

Guest
Jul 27

You won’t believe how many premium games are free on Steamunlocked.

Like

Guest
Jul 22

My gaming setup is complete thanks to Steamunlocked.

Like

kms pico
Apr 26

A melhor maneira de ativar seu sistema é usando o KMSPico Ativador. Ele funciona de forma silenciosa, sem prejudicar o desempenho do seu PC. Com o KMSPico Ativador, você ativa Windows e Office para sempre, sem pagar nada. Disponibilizamos a versão mais recente do KMSPico Ativador diretamente para você, sem vírus e sem enrolação. O processo é simples: um clique e tudo estará ativado. Liberte seu computador e aproveite tudo que ele tem a oferecer com o KMSPico Ativador.

Like
bottom of page