Start · Sprachen · JavaScript · Referenz · HTMLTemplateElement.shadowRootMode

HTMLTemplateElement.shadowRootMode

Eigenschaft

Liest oder setzt das Attribut <code>shadowrootmode</code> eines <code>&lt;template&gt;</code>-Elements, das den Modus eines deklarativen Shadow Roots festlegt (<code>"open"</code> oder <code>"closed"</code>).

seit JavaScript Baseline 2024 (Chrome/Edge 111+, Firefox 123+, Saf Kategorie: webapi

Signatur

HTMLTemplateElement.shadowRootMode

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

Typ
string
Beschreibung
"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));
"" open closed foo ""

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
open null

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);
DSD nativ unterstützt: true

// Wichtig · Fallstricke

  • Kein nachträglicher Effekt: Wenn du shadowRootMode an 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.
  • innerHTML ignoriert Declarative Shadow DOM. Nimm setHTMLUnsafe() oder Document.parseHTMLUnsafe(). Wie die Namen sagen, wird dabei nicht bereinigt: Ungeprüfte Nutzereingaben öffnen XSS-Lücken.
  • Bei "closed" gibt host.shadowRoot null zurück. Eine Custom-Element-Klasse erreicht den Shadow Root dann nur über this.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 standardisierte shadowrootmode gibt es seit Chrome 111, Safari 16.4 und Firefox 123.