Signatur
Beschreibung
CSSScopeRule ist die CSSOM-Darstellung einer @scope-Regel. Mit @scope gelten Stilregeln nur innerhalb eines bestimmten DOM-Teilbaums: Er beginnt bei der Scope-Wurzel (z. B. .card) und endet optional an einer Scope-Grenze (z. B. .card__content). So entsteht ein „Donut-Scope“, bei dem verschachtelte Bereiche ausgenommen werden.
Die Schnittstelle erbt von CSSGroupingRule. Deshalb stehen die verschachtelten Regeln über cssRules zur Verfügung und lassen sich mit insertRule() und deleteRule() ändern. Dazu kommen zwei eigene, schreibgeschützte Eigenschaften:
start(string | null): der Selektor der Scope-Wurzel, odernullbei einem impliziten Scope (@scope { … }innerhalb eines<style>-Elements).end(string | null): der Selektor der Scope-Grenze (der Teil nachto), odernull, wenn keine Grenze angegeben ist.
Einsatzgebiete sind vor allem Werkzeuge, die Stylesheets untersuchen oder umschreiben: DevTools-Erweiterungen, CSS-Linter im Browser, Laufzeit-Theming oder Komponentenbibliotheken, die Stile zur Laufzeit in ihren Scope einfügen. Instanzen legt man nie direkt an. Sie entstehen beim Parsen eines Stylesheets oder durch insertRule() bzw. CSSStyleSheet.replaceSync().
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $start | string | null | null | Schreibgeschützte Eigenschaft: Selektor der Scope-Wurzel, z. B. .card. Bei einem impliziten Scope ist der Wert null. |
| $end | string | null | null | Schreibgeschützte Eigenschaft: Selektor der Scope-Grenze (nach to). Ohne Grenze ist der Wert null. |
| $cssRules | CSSRuleList | Geerbt von CSSGroupingRule: die Liste der Regeln innerhalb des Scopes. |
|
| $insertRule(rule, index) | (string, number?) => number | index = 0 | Geerbt: fügt eine Regel an Position index in den Scope ein und gibt diesen Index zurück. |
| $deleteRule(index) | (number) => void | Geerbt: entfernt die Regel an Position index. |
Rückgabewert
CSSStyleSheet.cssRules oder in den cssRules anderer Gruppierungsregeln.Beispiele
@scope-Regeln im Dokument finden und auslesen
// Alle Stylesheets nach @scope-Regeln durchsuchen
const findScopeRules = (rules, found = []) => {
for (const rule of rules) {
if (rule instanceof CSSScopeRule) found.push(rule);
if (rule.cssRules) findScopeRules(rule.cssRules, found);
}
return found;
};
for (const sheet of document.styleSheets) {
try {
for (const scope of findScopeRules(sheet.cssRules)) {
console.log(`Wurzel: ${scope.start}, Grenze: ${scope.end}, Regeln: ${scope.cssRules.length}`);
}
} catch {
// Fremde Stylesheets ohne CORS lösen einen SecurityError aus
}
}
Scope-Regel mit einem konstruierbaren Stylesheet erzeugen
const sheet = new CSSStyleSheet();
sheet.replaceSync(`
@scope (.card) to (.card__content) {
img { border-radius: 8px; }
h2 { color: rebeccapurple; }
}
`);
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
const scopeRule = sheet.cssRules[0];
console.log(scopeRule instanceof CSSScopeRule); // true
console.log(scopeRule.start); // ".card"
console.log(scopeRule.end); // ".card__content"
Regeln zur Laufzeit in einen Scope einfügen und entfernen
const sheet = new CSSStyleSheet();
sheet.replaceSync('@scope (.theme-dark) { p { color: #eee; } }');
document.adoptedStyleSheets = [sheet];
const scope = sheet.cssRules[0];
// Neue Regel ans Ende des Scopes anhängen
const idx = scope.insertRule(':scope { background: #111; }', scope.cssRules.length);
console.log(scope.cssRules[idx].cssText);
// Wieder entfernen
scope.deleteRule(idx);
console.log(scope.cssRules.length);
Feature-Erkennung mit Fallback
const supportsScope = typeof CSSScopeRule !== 'undefined';
if (supportsScope) {
console.log('@scope wird unterstützt');
} else {
// Fallback: klassische Klassen-Präfixe oder Shadow DOM verwenden
document.documentElement.classList.add('no-css-scope');
}
// Wichtig · Fallstricke
- Browser-Kompatibilität: Chromium ab 118, Safari ab 17.4, Firefox erst seit Version 146. In älteren Browsern wird die ganze
@scope-Regel beim Parsen verworfen. Sie taucht dann auch nicht incssRulesauf. Vorher pertypeof CSSScopeRuleoderCSS.supports('selector(:scope)')und passendem Fallback prüfen. Achtung::scopegibt es schon länger, daher ist dieser zweite Test nur ein grober Hinweis. startundendsind schreibgeschützt. Um Wurzel oder Grenze zu ändern, entfernt man die Regel und fügt sie mit neuem Text wieder ein.- Bei einem impliziten Scope (
@scope { … }direkt in einem<style>) iststartgleichnull. Die Scope-Wurzel ist dann das Elternelement des<style>-Elements. - Stylesheets von fremden Ursprüngen ohne passende CORS-Header lösen beim Zugriff auf
cssRuleseinenSecurityErroraus. Deshalb den Zugriff intry…catchkapseln. @scopeändert die Kaskade: Bei gleicher Spezifität gewinnt die Regel mit der geringeren DOM-Nähe zur Scope-Wurzel (Scoping Proximity). Die Wurzel selbst erhöht die Spezifität der inneren Selektoren nicht.