Breadcrumbs

Accessing Shadow DOM Elements

Accessing Shadow DOM Elements

How to access shadow DOM elements

Shadow DOM elements are elements that are isolated from the main DOM of the web page: instead of being part of the main document subtree, they belong to a document fragment which is not as vulnerable to scripts (and styles) as normal DOM nodes.

We are currently able to tackle:

  • open or closed shadow roots: created by calling element.attachShadow or via declarative shadow DOM.

  • svg-use pattern: In SVG, the <use> element references and reuses existing elements defined elsewhere in the document.

The demarcators

The following snippets can handle the new demarcators:

  • hide-if-contains

  • hide-if-contains-image

  • hide-if-contains-similar-text

  • hide-if-contains-visible-text (^^sh^^ only, does NOT support ^^svg^^)

  • hide-if-contains-and-matches-style

  • hide-if-has-and-matches-style (currently only in selector and searchSelector params)

  • hide-if-labelled-by

  • simulate-mouse-event

Type of encapsulation

Demarcator

Selector example

How it works

open or closed shadow root

^^sh^^

.shadowRootParent ^^sh^^ span.childNode

The selector is split at the demarcator. The shadow root is accessed and nodes inside are targeted by the second part.

svg-use pattern

^^svg^^

.shadowRootParent ^^svg^^

The href or xlink:href attribute is extracted to find the matching original element by its id.

Browser compatibility

Snippets using the ^^sh^^ demarcator work only from Chrome 88+ and Opera 74+. The ^^sh^^ demarcator won't work on Chromium-based browsers (only extensions). Filters using unsupported demarcators fail silently without affecting the user experience.

How to write filters

Shadow roots

Write your CSS selector as usual: the first part should target the closest shadow root parent in the light DOM, then use ^^sh^^ and continue with references to nodes inside the shadow root.

1. Simple shadow root example:

HTML
<div class="myDiv">
   #shadow-root (closed)
  <span id="sponsored">Sponsored</span>
</div>

Filter:

example.com#$#hide-if-contains /Sponsored/ '.myDiv' '.myDiv ^^sh^^ #sponsored'

2. Nested shadow root example:

HTML
<div class="myDiv">
    #shadow-root (closed)
        <span class="mySpan">
            #shadow-root (closed)
                <span id="sponsored">Sponsored</span>
        </span>
</div>

Filter:

example.com#$#hide-if-contains /Sponsored/ '.myDiv' '.myDiv ^^sh^^ .mySpan ^^sh^^ #sponsored'

Svg-use pattern

1. Simple svg-use:

HTML
<svg>
    <text id="sponsored">Sponsored</text>
</svg>
<div class="myDiv">
    <svg class="mySvg">
        <use href="#sponsored"></use>
    </svg>
</div>

Filter:

example.com#$#hide-if-contains /Sponsored/ '.myDiv' '.myDiv .mySvg use ^^svg^^'

2. Referenced element has children:

HTML
<svg>
    <text id="sponsored">
        <tspan>Sponsored</tspan>
    </text>
</svg>

Filter:

example.com#$#hide-if-contains /Sponsored/ '.myDiv' '.myDiv .mySvg use ^^svg^^ tspan'

3. Nested <use> elements:

More than one ^^svg^^ demarcator can be used in the same selector to follow a series of nested <use> tags:

example.com#$#hide-if-contains /Sponsored/ '.myDiv' '.myDiv .mySvg use ^^svg^^ ^^svg^^'