JavaScript Element attachShadow() Method

Beginner
5 min read
Updated: Nov 2026
3 examples
Method

Definition

The Element.attachShadow() method attaches a shadow DOM tree to an element (the shadow host) and returns a ShadowRoot (MDN). You then put internal markup inside that root — the usual path for custom elements.

Pass the required arguments shown below. Check return values and browser support before you rely on the result.

Syntax

Call el.attachShadow. Start with this line.

JavaScript
el.attachShadow(options)
CallWhat it does
el.attachShadow(options)Primary signature.
el.attachShadow(...)Call with the arguments your case needs.

Built into the browser. Call attachShadow(...) on an Element — no import required.

Library declarations
JavaScript
el.attachShadow(options)

Parameters

ParameterDescription
options.modeRequired. "open" or "closed" encapsulation
Allowed hostRequired. Not every element can host a shadow root

Return Value

Return ValueDescription
*ShadowRoot to build into

JavaScript Examples

Example 1 — Open Shadow

Attach an open shadow root and append text inside it.

JavaScript
const host = document.getElementById("host");
const out = document.getElementById("out");

const root = host.attachShadow({ mode: "open" });
const span = document.createElement("span");
span.textContent = "Inside shadow";
root.append(span);

out.textContent =
  "shadowRoot text=" + host.shadowRoot.textContent;
Try It Yourself

How It Works

  1. Pick a host. A div is an allowed shadow host.
  2. Attach open. Returns a ShadowRoot you can build into.
  3. Append internal UI. Content lives in the shadow tree, not light DOM.
  4. Read later. host.shadowRoot works because mode is open.

Example 2 — Closed Shadow

With mode: "closed", shadowRoot is null — keep the return value.

JavaScript
const host = document.getElementById("host");
const out = document.getElementById("out");

const root = host.attachShadow({ mode: "closed" });
root.append("Secret UI");

out.textContent =
  "shadowRoot=" + String(host.shadowRoot) +
  " | kept root text=" + root.textContent;
Try It Yourself

How It Works

  1. Choose closed. Hides the root from element.shadowRoot.
  2. Save the return value. Your component code still needs that reference.
  3. Build with the saved root. Append works the same as open mode.
  4. Outside code sees null. That is the encapsulation difference.

Example 3 — Custom Element Host

Attach a shadow root in a custom element constructor, then append a label.

JavaScript
class HelloBox extends HTMLElement {
  constructor() {
    super();
    const root = this.attachShadow({ mode: "open" });
    const span = document.createElement("span");
    span.textContent = "Hello from shadow";
    root.append(span);
  }
}

customElements.define("hello-box", HelloBox);

const out = document.getElementById("out");
const el = document.createElement("hello-box");
document.getElementById("mount").append(el);
out.textContent = el.shadowRoot.textContent;
Try It Yourself

How It Works

  1. Extend HTMLElement. Autonomous custom elements can host shadow DOM.
  2. Call super() first. Required before using this.
  3. Attach in the constructor. Common pattern for component internals.
  4. Define, then create. customElements.define registers the tag.

Browser Support

Element.attachShadow() is Baseline Widely available on MDN (across browsers since January 2020). It is not Deprecated, Experimental, or Non-standard. Core open/closed modes are widely supported; newer options may need feature detection.

✓ Baseline Widely available

Element.attachShadow()

Programmatic ShadowRoot creation for custom elements and encapsulated UI. Widely available since 2020.

2020+ Widely available
Google Chrome 53+
Supported
Mozilla Firefox 63+
Supported
Apple Safari 10+
Supported
Microsoft Edge 79+
Supported
Opera 40+
Supported
Internet Explorer Not supported
Unavailable
attachShadow() Baseline

Bottom line: Safe for modern browsers. Prefer open mode unless you have a clear reason to close.

Frequently Asked Questions

It attaches a shadow DOM tree to an element (the shadow host) and returns a ShadowRoot (MDN). You then append markup inside that root for encapsulation.
No. MDN marks Element.attachShadow() as Baseline Widely available (across browsers since January 2020). It is not Deprecated, Experimental, or Non-standard. Some newer options may have narrower support.
With mode: "open", element.shadowRoot returns the ShadowRoot. With mode: "closed", element.shadowRoot is null — keep the return value from attachShadow() if you still need access from your own code.
No. Only certain elements can (for example div, span, section, headings, and custom elements). Some elements cannot for security reasons. Attaching to an unsupported element throws.
Calling attachShadow() again usually throws. A special case is a matching declarative shadow root: the existing ShadowRoot can be cleared and returned when modes match.
For open mode use host.shadowRoot. For closed mode use the ShadowRoot reference you saved from attachShadow().

Next: before()

Insert nodes or text before an element in its parent.

before() →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

15 people found this page helpful