Signatur
Beschreibung
Das Interface CSSNestedDeclarations gehört zum CSS Object Model (CSSOM) und wurde mit CSS Nesting eingeführt. Es steht für eine Gruppe normaler Eigenschafts-Deklarationen (z. B. color: red;), die innerhalb einer Stilregel nicht am Anfang stehen, sondern auf verschachtelte Regeln wie @media, &:hover oder .child { … } folgen. Solche Deklarationen landen nicht in der style-Eigenschaft der übergeordneten CSSStyleRule. Stattdessen erscheinen sie als eigenes CSSNestedDeclarations-Objekt in deren cssRules-Liste.
Wozu das gut ist: Früher hat der Browser Deklarationen nach verschachtelten Regeln stillschweigend an den Anfang der Regel „hochgezogen“. Dadurch ließ sich z. B. eine Eigenschaft in einer Media-Query nicht zuverlässig danach überschreiben. Mit CSSNestedDeclarations behält der Browser die Reihenfolge aus dem Quelltext bei, und die Kaskade verhält sich so, wie man es beim Lesen des CSS erwartet. Auch einfache Deklarationen direkt in einer verschachtelten @media- oder @supports-Regel werden als CSSNestedDeclarations dargestellt.
Das Interface erbt von CSSRule (also cssText, parentRule, parentStyleSheet usw.). Eine eigene Eigenschaft kommt hinzu:
style(nur lesbar): einCSSStyleDeclaration-Objekt (in neueren SpezifikationenCSSStyleProperties). Über dieses Objekt liest und änderst du die Deklarationen des Blocks.
Es gibt keinen öffentlichen Konstruktor. Solche Objekte entstehen nur, wenn der Browser verschachteltes CSS parst, etwa aus einem <style>-Element, über CSSStyleSheet.replaceSync() oder mit insertRule().
Rückgabewert
CSSStyleRule.cssRules oder in den cssRules verschachtelter Gruppierungsregeln. Über style greifst du auf die Deklarationen zu.Beispiele
Verschachtelte Deklarationen im CSSOM finden
const sheet = new CSSStyleSheet();
sheet.replaceSync(`
.card {
color: black;
@media (min-width: 600px) {
padding: 2rem;
}
background: white;
}
`);
const card = sheet.cssRules[0]; // CSSStyleRule
console.log(card.style.cssText); // nur Deklarationen VOR den verschachtelten Regeln
console.log(card.cssRules.length);
for (const rule of card.cssRules) {
console.log(rule.constructor.name);
}
const trailing = card.cssRules[1];
console.log(trailing instanceof CSSNestedDeclarations);
console.log(trailing.style.background);
Deklarationen innerhalb einer verschachtelten @media-Regel ändern
const sheet = new CSSStyleSheet();
sheet.replaceSync(`
.btn {
font-size: 1rem;
@media (prefers-reduced-motion: no-preference) {
transition: transform 0.2s;
}
}
`);
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
const media = sheet.cssRules[0].cssRules[0]; // CSSMediaRule
const decls = media.cssRules[0]; // CSSNestedDeclarations
// Übergangsdauer zur Laufzeit anpassen
decls.style.setProperty('transition', 'transform 0.5s ease-out');
console.log(decls.cssText);
Feature-Erkennung und rekursives Auslesen aller Deklarationen
const supportsNestedDecls = typeof CSSNestedDeclarations !== 'undefined';
console.log('CSSNestedDeclarations unterstützt:', supportsNestedDecls);
// Alle Deklarationsblöcke eines Stylesheets rekursiv sammeln
const collectDeclarations = (rules, out = []) => {
for (const rule of rules) {
if (rule instanceof CSSStyleRule) {
out.push({ selector: rule.selectorText, css: rule.style.cssText });
} else if (supportsNestedDecls && rule instanceof CSSNestedDeclarations) {
out.push({ selector: '(verschachtelt)', css: rule.style.cssText });
}
if (rule.cssRules) collectDeclarations(rule.cssRules, out);
}
return out;
};
const sheet = new CSSStyleSheet();
sheet.replaceSync('.a { color: red; &:hover { color: blue; } margin: 0; }');
console.table(collectDeclarations(sheet.cssRules));
// Wichtig · Fallstricke
- Browser-Kompatibilität: Unterstützt ab Chrome/Edge 130, Firefox 132 und Safari 18.2. Ältere Browser mit CSS-Nesting-Unterstützung ziehen nachfolgende Deklarationen an den Anfang der Stilregel hoch. Dort landen sie in
CSSStyleRule.style, und die Kaskade kann anders ausfallen. Prüfe die Unterstützung vorher mittypeof CSSNestedDeclarations !== 'undefined'. - Kein Konstruktor:
new CSSNestedDeclarations()wirft einenTypeError. Neue Blöcke fügst du überinsertRule()einerCSSStyleRuleoderCSSGroupingRuleein, z. B.rule.insertRule('color: red;', 0). - Code, der von
styleausgeht, liefert unvollständige Ergebnisse: Werkzeuge, die nurCSSStyleRule.styleauswerten (Linter, CSS-in-JS-Tools, Editor-Erweiterungen), übersehen Deklarationen nach verschachtelten Regeln. Durchlaufe immer auchcssRules. CSSNestedDeclarationshat keinenselectorText. Der Block gilt für den Selektor der übergeordneten Regel (parentRule).- Bei Stylesheets von fremden Ursprüngen ohne CORS-Freigabe löst der Zugriff auf
cssRuleseinenSecurityErroraus.