Start · Sprachen · JavaScript · Referenz · CSSStyleSheet.replaceSync()

CSSStyleSheet.replaceSync()

Methode

Ersetzt synchron alle Regeln eines konstruierten <code>CSSStyleSheet</code> durch den übergebenen CSS-Text; <code>@import</code>-Regeln werden dabei ignoriert.

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

Signatur

CSSStyleSheet.prototype.replaceSync(text)

Beschreibung

replaceSync() verwirft sofort alle Regeln eines Stylesheets und parst den übergebenen String als neuen Inhalt. Die Methode ist das synchrone Gegenstück zu replace() und eignet sich immer dann, wenn der CSS-Text bereits vorliegt und keine externen Ressourcen per @import nachgeladen werden müssen.

Sie funktioniert nur bei konstruierten Stylesheets, also bei Objekten, die mit new CSSStyleSheet() erzeugt wurden. Solche Stylesheets werden über document.adoptedStyleSheets oder shadowRoot.adoptedStyleSheets eingebunden. Das ist besonders bei Web Components praktisch: Ein einziges Stylesheet-Objekt kann von beliebig vielen Shadow Roots gemeinsam genutzt werden, ohne dass das CSS für jede Instanz neu geparst wird.

Änderungen über replaceSync() wirken sofort auf alle Dokumente und Shadow Roots, die das Stylesheet übernommen haben. So lassen sich z. B. Themes oder dynamisch erzeugte Styles zentral austauschen.

Parameter

Name Typ Default Beschreibung
$text Pflicht string CSS-Quelltext, der den bisherigen Inhalt vollständig ersetzt. Enthaltene @import-Regeln werden ignoriert (mit Konsolen-Warnung).

Beispiele

Konstruiertes Stylesheet für das Dokument

const sheet = new CSSStyleSheet();
sheet.replaceSync('body { font-family: system-ui; } .hinweis { color: crimson; }');

// Stylesheet dem Dokument hinzufügen, bestehende behalten
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];

console.log(sheet.cssRules.length);
2

Gemeinsames Stylesheet für Web Components

const buttonStyles = new CSSStyleSheet();
buttonStyles.replaceSync(`
  :host { display: inline-block; }
  button { padding: .5rem 1rem; border-radius: 6px; }
`);

class FancyButton extends HTMLElement {
  constructor() {
    super();
    const root = this.attachShadow({ mode: 'open' });
    // Alle Instanzen teilen sich dasselbe geparste Stylesheet
    root.adoptedStyleSheets = [buttonStyles];
    root.innerHTML = '<button><slot></slot></button>';
  }
}
customElements.define('fancy-button', FancyButton);

Theme zur Laufzeit wechseln

const theme = new CSSStyleSheet();
document.adoptedStyleSheets = [...document.adoptedStyleSheets, theme];

const setTheme = (dark) => {
  theme.replaceSync(dark
    ? ':root { --bg: #111; --fg: #eee; }'
    : ':root { --bg: #fff; --fg: #222; }');
};

setTheme(window.matchMedia('(prefers-color-scheme: dark)').matches);

Fehlerfall: nicht konstruiertes Stylesheet

const existing = document.styleSheets[0];
try {
  existing.replaceSync('p { color: red; }');
} catch (err) {
  console.log(err.name);
}
NotAllowedError

// Wichtig · Fallstricke

  • Nur konstruierte Stylesheets: Bei Stylesheets aus <style> oder <link> wirft der Aufruf eine NotAllowedError-DOMException.
  • @import wird ignoriert: Solche Regeln werden verworfen, ohne dass ein Fehler geworfen wird. Für Importe replace() verwenden (liefert ein Promise).
  • Ungültiges CSS führt nicht zu einer Ausnahme – fehlerhafte Regeln werden wie beim normalen CSS-Parsing einfach übersprungen.
  • Performance: Große CSS-Strings werden synchron auf dem Hauptthread geparst. Bei sehr umfangreichen Styles kann das kurzzeitig blockieren; für kleine Änderungen sind insertRule()/deleteRule() oft günstiger.
  • Kompatibilität: Konstruierbare Stylesheets gibt es erst seit Safari 16.4 und Firefox 101. Für ältere Browser auf <style>-Elemente im Shadow Root ausweichen. adoptedStyleSheets sollte man per Zuweisung eines neuen Arrays ändern; das direkte Ändern des Arrays (push()) wird erst in neueren Browsern unterstützt.
  • Sicherheit: CSS aus Benutzereingaben nicht ungeprüft einsetzen – über Attributselektoren und url() lassen sich Daten ausleiten (CSS-Injection).