Signatur
Beschreibung
Die Eigenschaft shadowRootMode spiegelt das HTML-Attribut shadowrootmode eines <template>-Elements wider. Das Attribut ist die Grundlage von Declarative Shadow DOM: Findet der HTML-Parser ein <template shadowrootmode="open">, hängt er direkt am Elternelement einen Shadow Root an, verschiebt den Template-Inhalt hinein und entfernt das <template> anschließend aus dem DOM. So lassen sich Web Components serverseitig rendern (SSR), ohne dass zuerst JavaScript mit attachShadow() laufen muss.
Es handelt sich um ein aufgezähltes Attribut mit den erlaubten Werten "open" und "closed". Der Getter liefert immer den kleingeschriebenen gültigen Wert. Fehlt das Attribut oder ist sein Wert ungültig, erhältst du einen leeren String "". Beim Setzen wird der übergebene String ohne Prüfung ins Attribut geschrieben.
Wichtig: Die Eigenschaft ist nur beim Parsen wirksam. Wenn du shadowRootMode nachträglich per JavaScript an einem bestehenden Template setzt, entsteht dadurch kein Shadow Root. Willst du deklaratives Shadow DOM dynamisch erzeugen, nimm Element.setHTMLUnsafe() oder Document.parseHTMLUnsafe(). innerHTML funktioniert dafür nicht.
Rückgabewert
"open", "closed" oder "" (leerer String), wenn das Attribut fehlt oder einen ungültigen Wert hat. Beim Setzen wird der String ins Attribut shadowrootmode geschrieben.Beispiele
Attribut lesen und setzen: so funktioniert das Spiegeln
const tpl = document.createElement('template');
console.log(JSON.stringify(tpl.shadowRootMode)); // Attribut fehlt
tpl.shadowRootMode = 'open';
console.log(tpl.getAttribute('shadowrootmode'));
tpl.setAttribute('shadowrootmode', 'CLOSED'); // Groß-/Kleinschreibung egal
console.log(tpl.shadowRootMode);
tpl.shadowRootMode = 'foo'; // ungültiger Wert
console.log(tpl.getAttribute('shadowrootmode'), JSON.stringify(tpl.shadowRootMode));
Deklaratives Shadow DOM dynamisch mit setHTMLUnsafe() einfügen
const host = document.createElement('div');
document.body.append(host);
host.setHTMLUnsafe(`
<user-card>
<template shadowrootmode="open">
<style>p { color: teal; }</style>
<p><slot></slot></p>
</template>
Ada Lovelace
</user-card>`);
const card = host.querySelector('user-card');
console.log(card.shadowRoot?.mode);
console.log(card.querySelector('template')); // Template wurde verbraucht
Feature-Erkennung vor dem Einsatz von Declarative Shadow DOM
const supportsDSD = 'shadowRootMode' in HTMLTemplateElement.prototype;
// Ersatzlösung: nicht verarbeitete Templates selbst anhängen
if (!supportsDSD) {
document.querySelectorAll('template[shadowrootmode]').forEach((tpl) => {
const mode = tpl.getAttribute('shadowrootmode');
const shadow = tpl.parentNode.attachShadow({ mode });
shadow.append(tpl.content);
tpl.remove();
});
}
console.log('DSD nativ unterstützt:', supportsDSD);
// Wichtig · Fallstricke
- Kein nachträglicher Effekt: Wenn du
shadowRootModean einem Template setzt, das schon im DOM hängt, entsteht kein Shadow Root. Das Attribut wertet nur der Parser aus. - Template verschwindet: Nach dem Parsen ist das
<template shadowrootmode>nicht mehr im DOM.querySelector('template[shadowrootmode]')findet es in unterstützenden Browsern also nicht. innerHTMLignoriert Declarative Shadow DOM. NimmsetHTMLUnsafe()oderDocument.parseHTMLUnsafe(). Wie die Namen sagen, wird dabei nicht bereinigt: Ungeprüfte Nutzereingaben öffnen XSS-Lücken.- Bei
"closed"gibthost.shadowRootnullzurück. Eine Custom-Element-Klasse erreicht den Shadow Root dann nur überthis.attachInternals().shadowRoot. - Wenn das Host-Element schon einen Shadow Root hat, wird das deklarative Template nicht angehängt, sondern bleibt als normales Template stehen.
- Kompatibilität: Chrome 90–110 kannte nur das nicht standardisierte Attribut
shadowroot. Das standardisierteshadowrootmodegibt es seit Chrome 111, Safari 16.4 und Firefox 123.