DEV Community

Cover image for 🌐 Understanding Shadow DOM and Web Components in JavaScript
Dipak Ahirav
Dipak Ahirav

Posted on

🌐 Understanding Shadow DOM and Web Components in JavaScript

The web has evolved significantly over the years, and one of the most exciting advancements is the introduction of Web Components and Shadow DOM. These technologies enable developers to create reusable and encapsulated components. Let's dive in! 🧙‍♂️

please subscribe to my YouTube channel to support my channel and get more web development tutorials.

📜 Table of Contents

  1. Introduction
  2. What are Web Components?
  3. Understanding the Shadow DOM
  4. Creating Web Components
  5. Working with Shadow DOM
  6. Example: Creating a Custom Element
  7. Benefits of Using Web Components and Shadow DOM
  8. Conclusion

📚 Introduction

Web Components and Shadow DOM are web standards that allow developers to create custom, reusable, and encapsulated HTML elements. These technologies enhance modularity and code reusability, making it easier to manage complex web applications.

🧩 What are Web Components?

Web Components are a set of web platform APIs that allow you to create custom, reusable HTML tags. They consist of three main technologies:

  1. Custom Elements: Define your own HTML elements.
  2. Shadow DOM: Encapsulate the internal structure and styling of a component.
  3. HTML Templates: Define chunks of markup that are inert until instantiated.

🌑 Understanding the Shadow DOM

The Shadow DOM is a key part of Web Components. It provides encapsulation for the internal structure of a component, ensuring that styles and scripts do not leak out or get affected by the rest of the page.

Benefits of Shadow DOM

  • Encapsulation: Styles and markup are scoped to the component.
  • Isolation: Components are isolated from the global scope, preventing conflicts.
  • Reusability: Components can be reused across different parts of an application without worrying about style conflicts.

🛠️ Creating Web Components

To create a Web Component, you need to define a custom element by extending the HTMLElement class and using the customElements.define method.

Example:

class MyElement extends HTMLElement {
  constructor() {
    super();
    // Attach a shadow root to the element.
    this.attachShadow({ mode: 'open' });
  }

  connectedCallback() {
    this.shadowRoot.innerHTML = `
      <style>
        p {
          color: blue;
        }
      </style>
      <p>Hello, Web Components!</p>
    `;
  }
}

customElements.define('my-element', MyElement);
Enter fullscreen mode Exit fullscreen mode

🌟 Working with Shadow DOM

The Shadow DOM is created using the attachShadow method. You can then use the shadow root to add markup and styles that are encapsulated within the component.

Example:

class MyShadowComponent extends HTMLElement {
  constructor() {
    super();
    const shadow = this.attachShadow({ mode: 'open' });

    const wrapper = document.createElement('div');
    const style = document.createElement('style');
    style.textContent = `
      div {
        color: white;
        background-color: black;
        padding: 10px;
      }
    `;

    wrapper.textContent = 'This is a shadow DOM component!';
    shadow.appendChild(style);
    shadow.appendChild(wrapper);
  }
}

customElements.define('my-shadow-component', MyShadowComponent);
Enter fullscreen mode Exit fullscreen mode

👨‍💻 Example: Creating a Custom Element

Let's create a custom <user-card> element to display user information.

user-card.js:

class UserCard extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
  }

  connectedCallback() {
    this.shadowRoot.innerHTML = `
      <style>
        .card {
          border: 1px solid #ccc;
          padding: 10px;
          border-radius: 5px;
          max-width: 200px;
        }
        .name {
          font-size: 20px;
          font-weight: bold;
        }
      </style>
      <div class="card">
        <div class="name">${this.getAttribute('name')}</div>
        <div class="email">${this.getAttribute('email')}</div>
      </div>
    `;
  }
}

customElements.define('user-card', UserCard);
Enter fullscreen mode Exit fullscreen mode

Usage in HTML:

<script src="user-card.js"></script>
<user-card name="John Doe" email="john@example.com"></user-card>
Enter fullscreen mode Exit fullscreen mode

✅ Benefits of Using Web Components and Shadow DOM

  1. Reusability: Create reusable components that can be shared across projects.
  2. Encapsulation: Keep your component’s styles and markup scoped, preventing conflicts.
  3. Modularity: Break down your application into smaller, manageable components.
  4. Maintainability: Simplify the maintenance and enhancement of your codebase.

🏁 Conclusion

Web Components and Shadow DOM provide a powerful way to build modular, reusable, and encapsulated components for the web. By leveraging these technologies, you can enhance the structure and maintainability of your applications. 🌟

🚀 Happy Coding!

Feel free to leave your comments or questions below. If you found this guide helpful, please share it with your peers and follow me for more web development tutorials. Happy coding!

please subscribe to my YouTube channel to support my channel and get more web development tutorials.

Follow and Subscribe:

Top comments (12)

Collapse
 
dannyengelman profile image
Danny Engelman • Edited

With one helper function

const createElement = (t,p) => Object.assign(document.createElement(t), p);
Enter fullscreen mode Exit fullscreen mode

You can make the constructor less verbose, and better extendable.

Also see: Dev.to - Web Components lesson #102 - 5 more lessons after #101

Collapse
 
neurabot profile image
Neurabot

Nice.

Collapse
 
hemantbhat profile image
Hemant Bhat

Great explanation

Collapse
 
dipakahirav profile image
Dipak Ahirav

Thanks

Collapse
 
litlyx profile image
Antonio | CEO at Litlyx.com

Really great work!

Collapse
 
dipakahirav profile image
Dipak Ahirav

Thanks

Collapse
 
dipakahirav profile image
Dipak Ahirav

Thank you @matin_mollapur

Collapse
 
ankit_kumar_41670acf33cf4 profile image
Ankit kumar

Great work

Collapse
 
dipakahirav profile image
Dipak Ahirav

Thanks @ankit_kumar_41670acf33cf4 For kind words, please subscribe to my YouTube channel to support my channel and get more web development tutorials. Thank You

Collapse
 
kspshnik profile image
Evgeny Karpel

What about Can I Use? )

Collapse
 
dannyengelman profile image
Danny Engelman

Support since 2018 in all modern browsers (when Edge switched to the Chromium engine)
(I would say 6 years, but that will be wrong in 2025, so you need a Web Component here to always display the correct number of years)

caniuse.com/?search=web%20components

Some comments may only be visible to logged-in visitors. Sign in to view all comments.