Start · Sprachen · JavaScript · Referenz · Document.adoptedStyleSheets

Document.adoptedStyleSheets

Eigenschaft

Liest oder setzt ein Array von konstruierten <code>CSSStyleSheet</code>-Objekten, die zusätzlich zu den regulären Stylesheets auf das Dokument angewendet werden.

seit JavaScript Baseline 2023: Chrome 73+, Edge 79+, Firefox 101+, Kategorie: webapi

Signatur

Document.adoptedStyleSheets

Beschreibung

Über document.adoptedStyleSheets wendest du konstruierte Stylesheets auf ein Dokument an. Das sind Stylesheets, die du mit new CSSStyleSheet() direkt in JavaScript erzeugst, ohne ein <style>- oder <link>-Element ins DOM einzufügen. Die übernommenen Stylesheets werden nach den Stylesheets aus document.styleSheets ausgewertet. Bei gleicher Spezifität gewinnen deshalb ihre Regeln.

Der größte Vorteil: Dasselbe CSSStyleSheet-Objekt lässt sich gleichzeitig vom Dokument und von beliebig vielen Shadow Roots nutzen, dort über ShadowRoot.adoptedStyleSheets. Der Browser parst das CSS nur einmal. Änderungen per replace(), replaceSync() oder insertRule() wirken sofort überall, wo das Stylesheet übernommen wurde. Das eignet sich besonders für Design-Tokens, Themes und Web Components.

Seit der aktuellen Spezifikation ist der Wert ein ObservableArray. Du kannst ihn also wie ein normales Array verändern, etwa mit push(), splice() oder durch Zuweisung an einen Index. Ältere Implementierungen gaben dagegen ein eingefrorenes Array zurück, das sich nur durch Neuzuweisung ersetzen ließ. Die Neuzuweisung eines ganzen Arrays funktioniert daher am sichersten in allen Browsern.

Rückgabewert

Typ
CSSStyleSheet[]
Beschreibung
Ein (beobachtbares) Array der übernommenen konstruierten Stylesheets. Standardmäßig ist es leer ([]). Wenn du etwas zuweist, muss jedes Element ein mit new CSSStyleSheet() erzeugtes Stylesheet sein.

Beispiele

Konstruiertes Stylesheet anlegen und übernehmen

// Stylesheet ohne <style>-Element erzeugen
const sheet = new CSSStyleSheet();
sheet.replaceSync(`
  body { font-family: system-ui, sans-serif; margin: 2rem; }
  .hinweis { color: darkorange; }
`);

// Auf das Dokument anwenden (bestehende Einträge bleiben erhalten)
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];

console.log(document.adoptedStyleSheets.length);
1

Theme zur Laufzeit umschalten

const hell = new CSSStyleSheet();
hell.replaceSync(':root { --bg: #fff; --fg: #111; }');

const dunkel = new CSSStyleSheet();
dunkel.replaceSync(':root { --bg: #111; --fg: #eee; }');

const basis = new CSSStyleSheet();
basis.replaceSync('body { background: var(--bg); color: var(--fg); }');

const setzeTheme = (modus) => {
  document.adoptedStyleSheets = [basis, modus === 'dunkel' ? dunkel : hell];
};

setzeTheme('dunkel');
console.log(document.adoptedStyleSheets.includes(dunkel));
true

Ein Stylesheet für Dokument und Shadow DOM teilen

const tokens = new CSSStyleSheet();
tokens.replaceSync(':host, :root { --akzent: rebeccapurple; }');

document.adoptedStyleSheets = [...document.adoptedStyleSheets, tokens];

class MeinButton extends HTMLElement {
  constructor() {
    super();
    const root = this.attachShadow({ mode: 'open' });
    const eigen = new CSSStyleSheet();
    eigen.replaceSync('button { background: var(--akzent); color: white; }');
    root.adoptedStyleSheets = [tokens, eigen];
    root.innerHTML = '<button><slot></slot></button>';
  }
}
customElements.define('mein-button', MeinButton);

// Eine Änderung wirkt sofort überall, wo das Stylesheet übernommen wurde
tokens.replaceSync(':host, :root { --akzent: teal; }');

Asynchron laden und wieder entfernen

const ladeStyles = async () => {
  const sheet = new CSSStyleSheet();
  await sheet.replace('.karte { border: 1px solid #ccc; padding: 1rem; }');
  document.adoptedStyleSheets.push(sheet); // ObservableArray (moderne Browser)
  return sheet;
};

const sheet = await ladeStyles();
// Später wieder entfernen
document.adoptedStyleSheets = document.adoptedStyleSheets.filter((s) => s !== sheet);
console.log(document.adoptedStyleSheets.includes(sheet));
false

// Wichtig · Fallstricke

  • Nur konstruierte Stylesheets: Stylesheets aus <style> oder <link>, zum Beispiel aus document.styleSheets[0], lösen beim Zuweisen einen NotAllowedError aus.
  • Dokumentgrenzen: Ein Stylesheet lässt sich nur in dem Dokument verwenden, in dem es konstruiert wurde. Das gilt auch für Shadow Roots darin. Die Übernahme in ein <iframe>-Dokument schlägt fehl.
  • Überschreiben statt ergänzen: document.adoptedStyleSheets = [sheet] ersetzt alle bisherigen Einträge. Andere Bibliotheken können dort ebenfalls Stylesheets hinterlegt haben. Ergänze deshalb am besten mit dem Spread-Operator.
  • Kein @import: In konstruierten Stylesheets wird @import ignoriert. replaceSync() verwirft solche Regeln, und replace() gibt eine Konsolenwarnung aus.
  • Kompatibilität: Die Eigenschaft ist seit Safari 16.4 (März 2023) in allen modernen Browsern verfügbar. Mutierende Methoden wie push() funktionieren erst seit der Umstellung auf das ObservableArray, also ab Chrome 99 und Firefox 101. Vorher war nur die Neuzuweisung möglich. Für ältere Umgebungen gibt es das Polyfill construct-style-sheets-polyfill. Zur Funktionserkennung dient 'adoptedStyleSheets' in Document.prototype.
  • Reihenfolge: Übernommene Stylesheets folgen in der Kaskade auf document.styleSheets. Innerhalb des Arrays gewinnt bei gleicher Spezifität das spätere Element.