Baseline Widely available *
The Element.attachShadow()
method attaches a shadow DOM tree to the specified element and returns a reference to its ShadowRoot
.
Note that you can't attach a shadow root to every type of element. There are some that can't have a shadow DOM for security reasons (for example <a>
).
The following is a list of elements you can attach a shadow root to:
<article>
<aside>
<blockquote>
<body>
<div>
<footer>
<header>
<main>
<nav>
<p>
<section>
<span>
The method may be called on an element that already has a declarative shadow root, provided the specified mode mode
matches the existing mode. In this case the ShadowRoot
that was already present will be cleared and returned. This allows for cases where, for example, server-side rendering has already declaratively created a shadow root, and then client-side code attempts to attach the root again.
Otherwise calling attachShadow()
on an element that already has a shadow root will throw an exception.
options
An object which contains the following fields:
mode
A string specifying the encapsulation mode for the shadow DOM tree. This can be one of:
open
Elements of the shadow root are accessible from JavaScript outside the root, for example using Element.shadowRoot
:
element.attachShadow({ mode: "open" });
element.shadowRoot; // Returns a ShadowRoot obj
closed
Denies access to the node(s) of a closed shadow root from JavaScript outside it:
element.attachShadow({ mode: "closed" });
element.shadowRoot; // Returns null
clonable
Optional
A boolean that specifies whether the shadow root is clonable: when set to true
, the shadow host cloned with Node.cloneNode()
or Document.importNode()
will include shadow root in the copy. Its default value is false
.
delegatesFocus
Optional
A boolean that, when set to true
, specifies behavior that mitigates custom element issues around focusability. When a non-focusable part of the shadow DOM is clicked, the first focusable part is given focus, and the shadow host is given any available :focus
styling. Its default value is false
.
serializable
Optional
A boolean that, when set to true
, indicates that the shadow root is serializable. If set, the shadow root may be serialized by calling the Element.getHTML()
or ShadowRoot.getHTML()
methods with the options.serializableShadowRoots
parameter set true
. Its default value is false
.
slotAssignment
Optional
A string specifying the slot assignment mode for the shadow DOM tree. This can be one of:
named
Elements are automatically assigned to <slot>
elements within this shadow root. Any descendants of the host with a slot
attribute which matches the name
attribute of a <slot>
within this shadow root will be assigned to that slot. Any top-level children of the host with no slot
attribute will be assigned to a <slot>
with no name
attribute (the "default slot") if one is present.
manual
Elements are not automatically assigned to <slot>
elements. Instead, they must be manually assigned with HTMLSlotElement.assign()
. Its default value is named
.
Returns a ShadowRoot
object.
NotSupportedError
DOMException
This error may be thrown when you try to attach a shadow root to an element:
disabledFeatures
has been given a value of "shadow"
.mode
does not match the existing mode.The following example is taken from our word-count-web-component demo (see it live also). You can see that we use attachShadow()
in the middle of the code to create a shadow root, which we then attach our custom element's contents to.
// Create a class for the element
class WordCount extends HTMLParagraphElement {
constructor() {
// Always call super first in constructor
super();
// count words in element's parent element
const wcParent = this.parentNode;
function countWords(node) {
const text = node.innerText || node.textContent;
return text
.trim()
.split(/\s+/g)
.filter((a) => a.trim().length > 0).length;
}
const count = `Words: ${countWords(wcParent)}`;
// Create a shadow root
const shadow = this.attachShadow({ mode: "open" });
// Create text node and add word count to it
const text = document.createElement("span");
text.textContent = count;
// Append it to the shadow root
shadow.appendChild(text);
// Update count when element content changes
this.parentNode.addEventListener("input", () => {
text.textContent = `Words: ${countWords(wcParent)}`;
});
}
}
// Define the new element
customElements.define("word-count", WordCount, { extends: "p" });
Disabling shadow DOM
If the element has a static property named disabledFeatures
, which is an array containing the string "shadow"
, then the attachShadow()
call will throw an exception.
For example:
class MyCustomElement extends HTMLElement {
// Disable shadow DOM for this element.
static disabledFeatures = ["shadow"];
constructor() {
super();
}
connectedCallback() {
// Create a shadow root.
// This will throw an exception.
const shadow = this.attachShadow({ mode: "open" });
}
}
// Define the new element
customElements.define("my-custom-element", MyCustomElement);
Specifications Browser compatibility See also
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4