Signatur
Beschreibung
CSS.escape() ist eine statische Methode des CSS-Namensraums. Sie nimmt einen beliebigen String entgegen und gibt ihn als gültigen CSS-Bezeichner (identifier) zurück. Zeichen, die in CSS eine besondere Bedeutung haben, etwa #, ., :, [, ], Leerzeichen oder Anführungszeichen, werden mit einem Backslash maskiert. Eine Ziffer am Anfang des Strings wird als hexadezimaler Code-Point mit folgendem Leerzeichen geschrieben (1 → \31 ).
Gebraucht wird die Methode vor allem, wenn Selektoren dynamisch zusammengesetzt werden, also wenn IDs, Klassennamen oder Attributwerte aus Benutzereingaben, Datenbanken oder generierten Werten (UUIDs, Zeitstempel, Dateinamen) stammen. Ohne Maskierung wirft document.querySelector() bei ungültigen Selektoren einen SyntaxError, oder der Selektor trifft unbemerkt die falschen Elemente.
Die Methode folgt dem Algorithmus „serialize an identifier“ aus der Spezifikation CSSOM. Dabei gilt:
- Das Nullzeichen
U+0000wird durchU+FFFDersetzt. - Steuerzeichen (
U+0001–U+001F,U+007F) werden als Hex-Code-Point maskiert. - Eine Ziffer am Anfang, oder direkt nach einem führenden
-, wird als Hex-Code-Point maskiert. - Ein einzelnes
-wird zu\-. - Buchstaben, Ziffern,
-,_und Nicht-ASCII-Zeichen (abU+0080) bleiben unverändert. Alle anderen Zeichen erhalten einen vorangestellten Backslash.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $ident Pflicht | string | Der zu maskierende String. Andere Werte werden vorher per String() in einen String umgewandelt, z. B. 123 → "123". |
Rückgabewert
Beispiele
Element mit Sonderzeichen in der ID finden
// ID stammt z. B. aus einem CMS und enthält Punkt und Doppelpunkt
const id = 'artikel.2024:teil#1';
// Ohne Maskierung: SyntaxError bzw. falscher Treffer
// document.querySelector(`#${id}`);
const selector = `#${CSS.escape(id)}`;
console.log(selector);
const el = document.querySelector(selector);
console.log(el?.id);
IDs, die mit einer Ziffer beginnen (z. B. generierte IDs)
console.log(CSS.escape('1abc')); // Ziffer am Anfang
console.log(CSS.escape('-1abc')); // Ziffer nach Bindestrich
console.log(CSS.escape('-')); // einzelner Bindestrich
console.log(CSS.escape('--var')); // bleibt unverändert
console.log(CSS.escape('a b')); // Leerzeichen
console.log(CSS.escape(42)); // Zahl wird zu String
// Praxis: Zeile einer Tabelle über eine numerische ID ansprechen
const rowId = 1024;
const row = document.querySelector(`#${CSS.escape(String(rowId))}`);
Attributselektor mit Benutzereingabe
// Filter anhand eines data-Attributs, Wert kommt aus einem Eingabefeld
const highlightCategory = (category) => {
const selector = `[data-category="${CSS.escape(category)}"]`;
document.querySelectorAll('.produkt').forEach((el) => el.classList.remove('aktiv'));
document.querySelectorAll(selector).forEach((el) => el.classList.add('aktiv'));
return selector;
};
console.log(highlightCategory('Kinder "Spiel" & Spaß'));
Dynamische CSS-Regel für einen Klassennamen erzeugen
const addColorRule = (className, color) => {
const sheet = new CSSStyleSheet();
sheet.replaceSync(`.${CSS.escape(className)} { color: ${color}; }`);
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
return sheet.cssRules[0].cssText;
};
// Klassennamen im Tailwind-Stil mit Doppelpunkt und Schrägstrich
console.log(addColorRule('md:w-1/2', 'rebeccapurple'));
// Wichtig · Fallstricke
- Nur für CSS gedacht:
CSS.escape()maskiert ausschließlich für die CSS-Syntax. Für HTML (innerHTML), URLs (encodeURIComponent()) oder JavaScript-Strings schützt die Methode nicht vor XSS oder Injection. - Nur einzelne Bezeichner maskieren: Übergib nie einen ganzen Selektor wie
CSS.escape('#id .klasse'), denn dann werden auch die gewollten#,.und Leerzeichen maskiert. Maskiere jeweils nur den variablen Teil. - Nicht nötig bei
getElementById():document.getElementById()undgetElementsByClassName()erwarten keinen Selektor, sondern den Rohwert. Wer dort maskiert, findet das Element nicht mehr. - Ohne Argument wirft der Aufruf einen
TypeError.CSS.escape(undefined)ergibt dagegen\"undefined\"undCSS.escape(null)ergibt\"null\", weil die Werte in Strings umgewandelt werden. Leere oder fehlende Werte solltest du deshalb vorher prüfen. - Kompatibilität: Die Methode wird von allen modernen Browsern unterstützt, nicht aber vom Internet Explorer. In Node.js gibt es kein globales
CSS-Objekt. In älteren Umgebungen oder in DOM-Nachbildungen für Tests (z. B. jsdom) kann die Methode fehlen. Dafür gibt es den Polyfillcss.escapevon Mathias Bynens (npm). - Die Konsole zeigt den Backslash einfach an (
\\#foo), im JavaScript-Stringliteral steht er dagegen doppelt:'\\\\#foo'.