Exploring CSS Shadow DOM and CSS Custom Shadow Parts

Published: (January 15, 2026 at 02:30 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

Modern web development emphasizes building reusable, encapsulated components—a goal the Shadow DOM and CSS Custom Shadow Parts directly address. These browser features isolate component internals from the global page, avoiding style leakage and conflicts while still allowing controlled customization.

What is Shadow DOM?

Shadow DOM is a web standard that lets you create a separate, encapsulated DOM subtree for an element, known as a shadow tree. The subtree’s markup and styling are isolated from the main document DOM, preventing unintended interference. It’s the foundational technology behind Web Components.

Encapsulation

Internal structure and styles are hidden from the main document and external CSS.

Scoped Styles

Styles inside the shadow tree only affect its nodes; page styles cannot bleed in.

Shadow Host

The regular DOM element that hosts the shadow tree.

Shadow Root

The root node of the shadow tree, created via JavaScript with attachShadow().

const host = document.querySelector('#host');
const shadow = host.attachShadow({ mode: 'open' });

const span = document.createElement('span');
span.textContent = "I'm inside the shadow DOM!";
shadow.appendChild(span);

Without Shadow DOM, outer‑page styles can accidentally override a component’s internal styles (and vice‑versa), making large apps harder to maintain. Shadow DOM creates a “style and markup bubble” around components, ensuring predictable behavior regardless of the surrounding page.

Styling Inside Shadow DOM

Since styles are scoped inside the shadow root, you style shadow‑DOM elements internally with regular CSS placed inside the shadow tree.

shadow.innerHTML = `
  
    span {
      color: red;
      border: 1px solid black;
    }
  
  Shadow DOM content
`;

This CSS applies only to elements inside the shadow tree, preventing conflicts with outside styles.

CSS Custom Shadow Parts

While Shadow DOM provides encapsulation, it also restricts customizing internal elements from outside. CSS Custom Shadow Parts let web components expose specific internal elements for external styling without breaking encapsulation.

/* External stylesheet */
my-component::part(button) {
  background-color: green;
  border-radius: 5px;
}

Example Component

class MyButton extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' }).innerHTML = `
      
        button {
          background-color: blue;
          color: white;
          padding: 10px;
          border: none;
          cursor: pointer;
        }
      
      Press me
    `;
  }
}
customElements.define('my-button', MyButton);

External styling

my-button::part(button) {
  background-color: orange; /* Override internal button style */
}

The external CSS targets the inner button’s part="button" while the rest of the component remains encapsulated.

Key Features

FeatureDescription
Shadow DOMEncapsulates markup and styles inside a shadow root, isolating from page styles.
Shadow HostRegular DOM element that hosts the shadow root.
Scoped StylesStyles inside the shadow root apply only within that tree.
CSS Custom Shadow PartsProvides a sanctioned way for external styling of internal component parts.
part attributeMarks internal elements to be exposed for external styling.
::part() selectorTargets parts from outside the shadow root for custom styling.

Conclusion

By using Shadow DOM and CSS Custom Shadow Parts, developers can create robust, maintainable web components that are both encapsulated and customizable—ushering in a new era of reusable UI building blocks.

Back to Blog

Related posts

Read more »

CSS Web Components for marketing sites

Article URL: https://hawkticehurst.com/2024/11/css-web-components-for-marketing-sites/ Comments URL: https://news.ycombinator.com/item?id=46679907 Points: 28 Co...

CSS variables explained for beginners

Introduction When writing CSS, you often repeat the same colors, font sizes, or spacing values again and again. This repetition makes your code harder to maint...