Signatur
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
[]). 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);
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));
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));
// Wichtig · Fallstricke
- Nur konstruierte Stylesheets: Stylesheets aus
<style>oder<link>, zum Beispiel ausdocument.styleSheets[0], lösen beim Zuweisen einenNotAllowedErroraus. - 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@importignoriert.replaceSync()verwirft solche Regeln, undreplace()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.