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.attachShadowor 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 |
|
|
The selector is split at the demarcator. The shadow root is accessed and nodes inside are targeted by the second part. |
|
svg-use pattern |
|
|
The |
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:
<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:
<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:
<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:
<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^^'