The Element.attachShadow() method attaches a shadow DOM tree to the specified element and returns a reference to its ShadowRoot.


var shadowroot = element.attachShadow(shadowRootInit); 


ShadowRootInit dictionary, which can contain the following field:

mode: A string specifying the encapsulation mode for the shadow DOM tree. This can be one of:

  • open: Specifies open encapsulation mode, which means elements of the shadow root are accessible from JavaScript outside the root, e.g. using Element.shadowRoot:
    element.shadowRoot; Returns a ShadowRoot obj
  • closed: Specifies closed encapsulation mode, which denies any access to the node(s) of a closed shadow root from JavaScript outside it:
    element.shadowRoot; // Returns null

Return value

Returns a ShadowRoot object.


Exception Explanation
InvalidStateError The element you are trying to attach to is already a shadow host.
NotSupportedError You are trying to attach a shadow root to an element outside the HTML namespace, or the element cannot have a shadow attached to it (see below).

Elements you can attach a shadow to

Note that you can't attach a shadow root to any element — there are some really obvious ones that can't have a shadow DOM for security reasons (for example <a>), and more besides. The following is a list of a elements you can attached a shadow root to:


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

    // count words in element's parent element
    var wcParent = this.parentNode;

    function countWords(node){
      var text = node.innerText || node.textContent
      return text.split(/\s+/g).length;

    var count = 'Words: ' + countWords(wcParent);

    // Create a shadow root
    var shadow = this.attachShadow({mode: 'open'});

    // Create text node and add word count to it
    var text = document.createElement('span');
    text.textContent = count;

    // Append it to the shadow root

    // Update count when element content changes
    setInterval(function() {
      var count = 'Words: ' + countWords(wcParent);
      text.textContent = count;
    }, 200)

// Define the new element
customElements.define('word-count', WordCount, { extends: 'p' });


Specification Status Comment
The definition of 'attachShadow()' in that specification.
Living Standard  

Browser compatibility

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help!

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
Basic support 53.0 No support No support 43.0 10.0
Feature Android Webview Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support 53.0 53.0 No support ? ? ?

Document Tags and Contributors

 Last updated by: chrisdavidmills,