Welche Zeichen sind in CSS-Klassennamen / Selektoren gültig?

1203

Welche Zeichen / Symbole sind in den CSS- Klassenselektoren zulässig ?
Ich weiß, dass die folgenden Zeichen ungültig sind , aber welche Zeichen sind gültig ?

~ ! @ $ % ^ & * ( ) + = , . / ' ; : " ? > < [ ] \ { } | ` #
Darryl Hein
quelle
5
Verwandte Frage: stackoverflow.com/questions/2812072/…
BalusC
32
Was ist mit utf8 Zeichen? Als
ob
9
Sonderzeichen können durch austretendes sie in Klassennamen verwendet werden - in Ihrer CSS - Datei Sie definieren können , .hello/worlddurch die Flucht der Backslash Klasse: .hello\2fworld, hello\2f worldoderhello\/world
wyqydsyq
1
Eine weitere verwandte Frage, nicht zur "Syntax von Namen", sondern zur "Syntax von Klassenattributen" beim Ausdrücken mehrerer Namen .
Peter Krauss
2
Sie können auch Emoji verwenden. npmjs.com/package/postcss-modules-emoji-classname
Kevin Suttle

Antworten:

1024

Sie können direkt in der CSS-Grammatik überprüfen .

Grundsätzlich 1 muss ein Name mit einem Unterstrich (beginnen _), einen Bindestrich ( -) oder einen Brief ( a- z), gefolgt von einer beliebigen Anzahl von Bindestrichen, Unterstrichen, Buchstaben oder Zahlen. Es gibt einen Haken: Wenn das erste Zeichen ein Bindestrich ist, muss das zweite Zeichen 2 ein Buchstabe oder ein Unterstrich sein und der Name muss mindestens 2 Zeichen lang sein.

-?[_a-zA-Z]+[_a-zA-Z0-9-]*

Kurz gesagt, die vorherige Regel wird wie folgt übersetzt und aus der W3C-Spezifikation extrahiert . ::

In CSS können Bezeichner (einschließlich Elementnamen, Klassen und IDs in Selektoren) nur die Zeichen [a-z0-9] und ISO 10646-Zeichen U + 00A1 und höher sowie den Bindestrich (-) und den Unterstrich (_) enthalten. ;; Sie können nicht mit einer Ziffer oder einem Bindestrich gefolgt von einer Ziffer beginnen. Bezeichner können auch maskierte Zeichen und jedes ISO 10646-Zeichen als numerischen Code enthalten (siehe nächster Punkt). Zum Beispiel die Kennung "B & W?" kann geschrieben werden als "B \ & W \?" oder "B \ 26 W \ 3F".

Bezeichner, die mit einem Bindestrich oder Unterstrich beginnen, sind normalerweise für browserspezifische Erweiterungen reserviert, wie in -moz-opacity .

1 Durch die Aufnahme von maskierten Unicode-Zeichen (die niemand wirklich verwendet) wird alles etwas komplizierter.

2 Beachten Sie, dass gemäß der von mir verknüpften Grammatik eine Regel, die mit ZWEI Bindestrichen beginnt, z --indent1. B. ungültig ist. Ich bin mir jedoch ziemlich sicher, dass ich dies in der Praxis gesehen habe.

Triptychon
quelle
57
NB: Das W3C sagt, dass die Verwendung eines führenden '-' oder '_' für herstellerspezifische CSS-Erweiterungen reserviert werden sollte (z. B. -moz * -Klassen, die von Mozilla-Browsern implementiert werden).
Mipadi
3
Die \ -escapes werden häufig verwendet, aber im Allgemeinen hauptsächlich für CSS-Hacks, um Browser zu isolieren, die sie nicht unterstützen.
Bobince
5
Um den Kommentar von @Pim Jager über zwei Jahre später zu aktualisieren, wird IE6 laut w3counter.com/globalstats.php jetzt von weniger als 3% der Benutzer verwendet, hinter IE9 bei 4%, IE7 bei 9%, IE8 bei 22%. Alle Versionen von Firefox haben 28%, alle Versionen von Chrome haben 17%.
Daniel Earwicker
3
Ich weiß, dass dies eine alte Antwort ist, aber CSS (mindestens 2+) erlaubt jedes {Nicht-ASCII} -Zeichen in Bezeichnern.
user2864740
11
In CSS, identifiers (including element names, classes, and IDs in selectors) can contain only the characters [a-zA-Z0-9] and ISO 10646 characters U+00A0 and higher, plus the hyphen (-) and the underscore (_); they cannot start with a digit, two hyphens, or a hyphen followed by a digit. Identifiers can also contain escaped characters and any ISO 10646 character as a numeric code (see next item). For instance, the identifier "B&W?" may be written as "B\&W\?" or "B\26 W\3F". Also - --indent1ist ungültig und muss \--indent1--
maskiert
177

Zu meiner Überraschung sind die meisten Antworten hier falsch. Es stellt sich heraus, dass:

Jedes Zeichen außer NUL ist in CSS-Klassennamen in CSS zulässig. (Wenn CSS NUL enthält (maskiert oder nicht), ist das Ergebnis undefiniert. [ CSS-Zeichen ])

Mathias Bynens' Antwort Links zu Erklärungen und Demos zeigen , wie diese Namen zu verwenden. In CSS-Code geschrieben, muss ein Klassenname möglicherweise maskiert werden werden, dies ändert jedoch nichts am Klassennamen. Beispielsweise sieht eine unnötig überstrichene Darstellung anders aus als andere Darstellungen dieses Namens, bezieht sich jedoch immer noch auf denselben Klassennamen.

Die meisten anderen (Programmier-) Sprachen haben nicht das Konzept, Variablennamen („Bezeichner“) zu maskieren, daher müssen alle Darstellungen einer Variablen gleich aussehen. Dies ist in CSS nicht der Fall.

Beachten Sie, dass es in HTML keine Möglichkeit gibt, Leerzeichen (Leerzeichen, Tabulator, Zeilenvorschub, Formularvorschub und Wagenrücklauf) in ein Klassennamenattribut aufzunehmen , da sie bereits Klassen voneinander trennen.

Wenn Sie also eine zufällige Zeichenfolge in einen CSS-Klassennamen umwandeln müssen: Achten Sie auf NUL und Leerzeichen und maskieren Sie (entsprechend für CSS oder HTML). Erledigt.

Robert Siemer
quelle
7
Die erste Zeile Ihrer Antwort sollte lauten: "Die meisten Antworten hier sind veraltet / gelten nur für CSS2".
Salman A
7
@ SalmanA Die Antworten, auf die ich mich beziehe, waren von Anfang an falsch. Sie gelten weder für CSS2.1, CSS2 noch für CSS1.
Robert Siemer
@ RobertSiemer guter Punkt, ich habe meinen Kommentar auf stackoverflow.com/questions/50812118/… verschoben (was immer weniger mit diesem Thema zu tun hat )
Peter T.
Und JavaScript-Implementierung: github.com/mathiasbynens/CSS.escape/blob/master/css.escape.js
Duarte Cunha Leão
71

Ich habe Ihre Frage hier ausführlich beantwortet: http://mathiasbynens.be/notes/css-escapes

Der Artikel erklärt auch, wie man Zeichen in CSS (und JavaScript) maskiert, und ich habe auch dafür ein praktisches Tool erstellt . Von dieser Seite:

Wenn Sie einem Element einen ID-Wert von geben würden ~!@$%^&*()_+-=,./';:"?><[]{}|`#, würde der Selektor folgendermaßen aussehen:

CSS:

<style>
  #\~\!\@\$\%\^\&\*\(\)\_\+-\=\,\.\/\'\;\:\"\?\>\<\[\]\\\{\}\|\`\#
  {
    background: hotpink;
  }
</style>

JavaScript:

<script>
  // document.getElementById or similar
  document.getElementById('~!@$%^&*()_+-=,./\';:"?><[]\\{}|`#');
  // document.querySelector or similar
  $('#\\~\\!\\@\\$\\%\\^\\&\\*\\(\\)\\_\\+-\\=\\,\\.\\/\\\'\\;\\:\\"\\?\\>\\<\\[\\]\\\\\\{\\}\\|\\`\\#');
</script>
Mathias Bynens
quelle
4
@Darryl Natürlich ist dies ein ziemlich extremes Beispiel, aber solche Dinge class="404-error"können nützlich sein.
Mathias Bynens
Ich habe ein Beispiel: Ich konvertiere eine Syntax, die die Ausgabe des Systems hervorhebt, in CSS. Es hat Klassennamen wie "ISO C ++: Typen ( _t / _type)". Wenn ich nur Leerzeichen ersetze, habe ich gültige Klassennamen.
fliegende Schafe
Auf Ihrer Website sagen Sie, dass das Leerzeichen mit einem Backslash versehen werden kann. Wenn ich es in einem Klassennamen versuche, kann ich es nicht zum Laufen bringen. Ich stelle fest, dass in diesem Beispiel kein Platz vorhanden ist. Ist es möglich?
Adamarla
@Adamarla <p class="foo bar">fügt dem pElement zwei Klassen hinzu : foo, undbar . Es gibt keine Möglichkeit (die ich mir vorstellen kann), einem HTML-Element einen Klassennamen hinzuzufügen, der Leerzeichen enthält. Die Informationen zum Escapezeichen von Leerzeichen wurden eingefügt, da es nützlich ist, solche Zeichen in anderen Bezeichnerkontexten, z. B. Namen von Schriftfamilien, zu maskieren.
Mathias Bynens
3
Wie bei den meisten Dingen im Leben scheint es bei CSS einen Unterschied zwischen "technisch legal bis zum Äußersten" und "gesund" zu geben.
Volksman
69

Lesen Sie die W3C-Spezifikation . (Dies ist CSS 2.1. Finden Sie die geeignete Version für Ihre Annahme von Browsern.)

bearbeiten: relevanter Absatz folgt:

In CSS können Bezeichner (einschließlich Elementnamen, Klassen und IDs in Selektoren) nur die Zeichen [a-z0-9] und ISO 10646-Zeichen U + 00A1 und höher sowie den Bindestrich (-) und den Unterstrich (_) enthalten. ;; Sie können nicht mit einer Ziffer oder einem Bindestrich gefolgt von einer Ziffer beginnen. Bezeichner können auch maskierte Zeichen und beliebige ISO 10646-Zeichen als numerischen Code enthalten (siehe nächster Punkt). Zum Beispiel die Kennung "B & W?" kann geschrieben werden als "B \ & W \?" oder "B \ 26 W \ 3F".

edit 2: wie @mipadi in Triptychs Antwort hervorhebt, gibt es diese Einschränkung , auch auf derselben Webseite:

In CSS können Bezeichner mit '-' (Bindestrich) oder '_' (Unterstrich) beginnen. Schlüsselwörter und Eigenschaftsnamen, die mit '-' oder '_' beginnen, sind für herstellerspezifische Erweiterungen reserviert. Solche herstellerspezifischen Erweiterungen sollten eines der folgenden Formate haben:

'-' + vendor identifier + '-' + meaningful name 
'_' + vendor identifier + '-' + meaningful name

Beispiel (e):

Wenn die XYZ-Organisation beispielsweise eine Eigenschaft hinzugefügt hat, um die Farbe des Rahmens auf der Ostseite der Anzeige zu beschreiben, wird sie möglicherweise als -xyz-border-east-color bezeichnet.

Andere bekannte Beispiele:

 -moz-box-sizing
 -moz-border-radius
 -wap-accesskey

Es wird garantiert, dass ein anfänglicher Bindestrich oder Unterstrich niemals in einer Eigenschaft oder einem Schlüsselwort von einer aktuellen oder zukünftigen CSS-Ebene verwendet wird. Daher erkennen typische CSS-Implementierungen solche Eigenschaften möglicherweise nicht und ignorieren sie möglicherweise gemäß den Regeln für die Behandlung von Analysefehlern. Da der erste Bindestrich oder Unterstrich Teil der Grammatik ist, sollten CSS 2.1-Implementierer immer in der Lage sein, einen CSS-konformen Parser zu verwenden, unabhängig davon, ob sie herstellerspezifische Erweiterungen unterstützen oder nicht.

Autoren sollten herstellerspezifische Erweiterungen vermeiden

Jason S.
quelle
Ich bezog mich auf Ihre zweite Ausgabe über führende Bindestriche und Unterstriche, habe aber vergessen, dies zu klären. Entschuldigung für die Verwirrung.
Albin
24

Der vollständige reguläre Ausdruck lautet:

-?(?:[_a-z]|[\200-\377]|\\[0-9a-f]{1,6}(\r\n|[ \t\r\n\f])?|\\[^\r\n\f0-9a-f])(?:[_a-z0-9-]|[\200-\377]|\\[0-9a-f]{1,6}(\r\n|[ \t\r\n\f])?|\\[^\r\n\f0-9a-f])*

Daher sind alle aufgelisteten Zeichen außer " -" und " _" nicht zulässig, wenn sie direkt verwendet werden. Sie können sie jedoch mit einem Backslash foo\~baroder der Unicode-Notation codieren foo\7E bar.

Gumbo
quelle
warum [\200-\377]? [\178-\1114112]ist in CSS 3 ohne Flucht erlaubt
fliegende Schafe
\377hier ist eigentlich falsch. In der Grammatik des Lexical Scanner-Abschnitts von CSS2.1 heißt es: "Das" \ 377 "stellt die höchste Zeichennummer dar, mit der aktuelle Versionen von Flex umgehen können (Dezimalzahl 255). Es sollte als" \ 4177777 "( Dezimalzahl 1114111), dies ist der höchstmögliche Codepunkt in Unicode / ISO-10646. " Es sollte auch von \240nicht sein \377. Ich denke, das ist jetzt 7 Jahre alt, also haben sich die Dinge seitdem wahrscheinlich ein bisschen geändert.
James Donnelly
1
Ich glaube, ein genauerer regulärer Ausdruck wäre -?(?:[_a-z]|(?![\u0000-\u0239]).*|\\[0-9a-f]{1,6}(\r\n|[ \t\r\n\f])?|\\[^\r\n\f0-9a-f])(?:[_a-z0-9-]|(?![\u0000-\u0239]).*|\\[0-9a-f]{1,6}(\r\n|[ \t\r\n\f])?|\\[^\r\n\f0-9a-f])*.
James Donnelly
2
@ JamesDonnelly Bitte zögern Sie nicht, meine Antwort zu bearbeiten, wenn Sie der Meinung sind, dass ein Update erforderlich ist.
Gumbo
11

Für diejenigen, die nach einer Problemumgehung suchen, können Sie beispielsweise eine Attributauswahl verwenden, wenn Ihre Klasse mit einer Zahl beginnt. Veränderung:

.000000-8{background:url(../../images/common/000000-0.8.png);} /* DOESN'T WORK!! */

dazu:

[class="000000-8"]{background:url(../../images/common/000000-0.8.png);} /* WORKS :) */

Wenn es mehrere Klassen gibt, müssen Sie sie meiner Meinung nach im Selektor angeben.

Quellen:

  1. https://benfrain.com/when-and-where-you-can-use-numbers-in-id-and-class-names/
  2. Gibt es eine Problemumgehung, um CSS-Klassen mit Namen zu erstellen, die mit gültigen Zahlen beginnen?
D.Tate
quelle
5

Mein Verständnis ist, dass der Unterstrich technisch gültig ist. Auschecken:

https://developer.mozilla.org/en/underscores_in_class_and_id_names

"... Errata gemäß der Anfang 2001 veröffentlichten Spezifikation unterstrichen erstmals legal."

Der oben verlinkte Artikel besagt, dass sie niemals verwendet werden, und enthält dann eine Liste von Browsern, die sie nicht unterstützen. Alle Browser sind zumindest in Bezug auf die Anzahl der Benutzer lange redundant.

mofaha
quelle
4

Bei HTML5 / CSS3 können Klassen und IDs mit Zahlen beginnen.

Marius
quelle
1
Hast du eine Quelle dafür? Vielleicht fehlt mir etwas, aber die CSS3-Selektorspezifikation verweist auf die Bezeichnerdefinition in der CSS 2.1-Spezifikation, die keine führenden Nummern zulässt.
Ryan
11
w3.org/TR/2003/WD-css3-syntax-20030813/#characters <- erlaubt immer noch keine führenden Nummern usw. (obwohl es funktioniert)
Jamie Pate
10
In HTML 5 können Klassen und IDs mit einer Zahl beginnen (z class="1a". B. ). Ein CSS-Bezeichner kann jedoch nicht mit einer Nummer beginnen (z. B. .1afunktioniert nicht). Sie können es entkommen, hart (zB .\31 aoder .\000031a).
Oriol
Es funktioniert zwar normalerweise auch in CSS, sieht aber so aus, als wäre es immer noch nicht offiziell. "Eigenschaftsnamen und Regelnamen sind immer Bezeichner, die mit einem Buchstaben oder einem Bindestrich gefolgt von einem Buchstaben beginnen müssen und dann Buchstaben, Zahlen, Bindestriche oder Unterstriche enthalten können." - w3.org/TR/css3-syntax/#syntax-description
Aufkleber
@Pangloss Aber Klassennamen sind keine Eigenschaftsnamen oder Regelnamen.
Bennett McElwee
1

Wenn Sie die Antwort von @ Triptych verlassen, können Sie die folgenden 2 Regex-Übereinstimmungen verwenden, um eine Zeichenfolge gültig zu machen:

[^a-z0-9A-Z_-]

Dies ist eine umgekehrte Übereinstimmung, bei der alles ausgewählt wird, was kein Buchstabe, keine Zahl, kein Bindestrich oder kein Unterstrich ist, um das Entfernen zu vereinfachen.

^-*[0-9]+

Dies entspricht 0 oder 1 Strichen, gefolgt von 1 oder mehr Zahlen am Anfang einer Zeichenfolge, auch zum einfachen Entfernen.

Wie ich es in PHP benutze:

//Make alphanumeric with dashes and underscores (removes all other characters)
$class = preg_replace("/[^a-z0-9A-Z_-]/", "", $class);
//Classes only begin with an underscore or letter
$class = preg_replace("/^-*[0-9]+/", "", $class);
//Make sure the string is 2 or more characters long
return 2 <= strlen($class) ? $class : '';
Manny Fleurmond
quelle