Które znaki są poprawne w nazwach / selektorach klas CSS?

1203

Jakie znaki / symbole są dozwolone w selektorach klas CSS ?
Wiem, że następujące znaki są nieprawidłowe , ale jakie znaki są prawidłowe ?

~ ! @ $ % ^ & * ( ) + = , . / ' ; : " ? > < [ ] \ { } | ` #
Darryl Hein
źródło
5
Powiązane pytanie: stackoverflow.com/questions/2812072/…
BalusC
32
co ze znakami utf8?
Jakbym
9
Znaki specjalne mogą być używane w nazwach klas przez ich ucieczki - w pliku CSS można zdefiniować .hello/worldklasę ucieczki backslash: .hello\2fworld, hello\2f worldlubhello\/world
wyqydsyq
1
Kolejne powiązane pytanie, nie o „składnię nazw”, ale o „składnię atrybutu klasy” przy wyrażaniu wielu nazw .
Peter Krauss,
2
Możesz także użyć emoji. npmjs.com/package/postcss-modules-emoji-classname
Kevin Suttle

Odpowiedzi:

1024

Możesz to sprawdzić bezpośrednio w gramatyce CSS .

Zasadniczo 1 , nazwa musi zaczynać się znakiem podkreślenia ( _), łącznikiem ( -) lub literą ( a- z), po której następuje dowolna liczba myślników, znaków podkreślenia, liter lub cyfr. Istnieje pewien haczyk: jeśli pierwszy znak jest łącznikiem, drugi znak musi mieć 2 litery lub znak podkreślenia, a nazwa musi mieć co najmniej 2 znaki.

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

Krótko mówiąc, poprzednia reguła przekłada się na następujące, wyodrębnione ze specyfikacji W3C. :

W CSS identyfikatory (w tym nazwy elementów, klasy i identyfikatory w selektorach) mogą zawierać tylko znaki [a-z0-9] i ISO 10646 znaków U + 00A1 i wyższe, a także łącznik (-) i podkreślenie (_) ; nie mogą zaczynać się cyfrą ani myślnikiem, po którym następuje cyfra. Identyfikatory mogą także zawierać znaki zmiany znaczenia i dowolny znak ISO 10646 jako kod numeryczny (patrz następny punkt). Na przykład identyfikator „B&W?” może być zapisane jako „B \ & W \?” lub „B \ 26 W \ 3F”.

Identyfikatory zaczynające się od łącznika lub podkreślenia są zwykle zarezerwowane dla rozszerzeń specyficznych dla przeglądarki, jak w -moz-opacity.

1 Wszystko to jest nieco bardziej skomplikowane przez włączenie znaków ucieczki Unicode (których tak naprawdę nikt nie używa).

2 Zauważ, że zgodnie z gramatyką, którą podłączyłem, reguła zaczynająca się od DWÓCH łączników, np. --indent1, Jest nieprawidłowa. Jestem jednak pewien, że widziałem to w praktyce.

Tryptyk
źródło
57
Uwaga: W3C mówi, że użycie wiodących „-” lub „_” powinno być zastrzeżone dla specyficznych dla dostawcy rozszerzeń CSS (np. Klasy -moz * zaimplementowane w przeglądarkach Mozilla).
mipadi
3
Kształty \ są powszechnie używane, ale generalnie głównie do celów włamań CSS, izolując przeglądarki, które ich nie obsługują.
bobince
5
Aby zaktualizować komentarz @Pim Jager ponad dwa lata później, według w3counter.com/globalstats.php IE6 jest teraz używany przez mniej niż 3% użytkowników, za IE9 na 4%, IE7 na 9%, IE8 na 22%. Wszystkie wersje Firefoksa mają 28%, wszystkie wersje Chrome mają 17%.
Daniel Earwicker
3
Wiem, że to stara odpowiedź, ale CSS (co najmniej 2+) dopuszcza dowolny identyfikator {Non-ASCII} w identyfikatorach.
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". Więc - --indent1jest nieprawidłowy i należy go uciec, ponieważ \--indent1( --klasy psują się na iOS, na przykład)
eithed
177

Ku mojemu zaskoczeniu większość odpowiedzi tutaj jest błędna. Okazało się, że:

Dowolny znak oprócz NUL jest dozwolony w nazwach klas CSS w CSS. (Jeśli CSS zawiera NUL (znak ucieczki lub nie), wynik jest niezdefiniowany. [ Znaki CSS ])

Odpowiedź Mathiasa Bynensa prowadzi do wyjaśnień i prezentacji pokazujących, jak używać tych nazw. Zapisana w kodzie CSS nazwa klasy może wymagać ucieczki , ale to nie zmienia nazwy klasy. Np. Niepotrzebnie przesadna reprezentacja będzie wyglądać inaczej niż inne reprezentacje tej nazwy, ale nadal odnosi się do tej samej nazwy klasy.

Większość innych języków (programowania) nie ma pojęcia ucieczki nazw zmiennych („identyfikatorów”), więc wszystkie reprezentacje zmiennej muszą wyglądać tak samo. W CSS tak nie jest.

Zauważ, że w HTML nie ma sposobu na umieszczenie znaków spacji (spacja, tabulator, przesunięcie wiersza, wysuw formularza i powrót karetki) w atrybucie nazwy klasy , ponieważ już one oddzielają klasy od siebie.

Tak więc, jeśli chcesz zmienić losowy ciąg znaków w nazwę klasy CSS: zadbaj o NUL i spację i ucieknij (odpowiednio dla CSS lub HTML). Gotowy.

Robert Siemer
źródło
7
Pierwszy wiersz Twojej odpowiedzi powinien brzmieć „większość odpowiedzi tutaj jest nieaktualna / dotyczy tylko CSS2”.
Salman A
7
@ SalmanA Odpowiedzi, o których mówię, od samego początku były błędne. Nie dotyczą one CSS2.1, CSS2 ani CSS1.
Robert Siemer
@RobertSiemer dobry punkt, przeniosłem swój komentarz na stackoverflow.com/questions/50812118/… (który nigdy nie jest mniej związany z tym tematem)
Peter T.,
I implementacja JavaScript: github.com/mathiasbynens/CSS.escape/blob/master/css.escape.js
Duarte Cunha Leão
71

Dokładnie odpowiedziałem na twoje pytanie tutaj: http://mathiasbynens.be/notes/css-escapes

W artykule wyjaśniono także, jak uciec przed dowolną postacią w CSS (i JavaScript), i zrobiłem też przydatne narzędzie do tego. Z tej strony:

Gdyby nadać elementowi wartość identyfikatora ~!@$%^&*()_+-=,./';:"?><[]{}|`#, selektor wyglądałby następująco:

CSS:

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

JavaScript:

<script>
  // document.getElementById or similar
  document.getElementById('~!@$%^&*()_+-=,./\';:"?><[]\\{}|`#');
  // document.querySelector or similar
  $('#\\~\\!\\@\\$\\%\\^\\&\\*\\(\\)\\_\\+-\\=\\,\\.\\/\\\'\\;\\:\\"\\?\\>\\<\\[\\]\\\\\\{\\}\\|\\`\\#');
</script>
Mathias Bynens
źródło
4
@Darryl Oczywiście jest to dość ekstremalny przykład, ale takie rzeczy class="404-error"mogą być przydatne.
Mathias Bynens
mam przykład: przekonwertowałem dane wyjściowe systemu podświetlania składni na CSS. ma nazwy klas, takie jak „ISO C ++: Typy ( _t / _type)”. jeśli zastąpię tylko białe znaki, mam prawidłowe nazwy klas.
latające owce
Na swojej stronie mówisz, że znak spacji może być poprzedzony odwrotnym ukośnikiem. Kiedy próbuję tego w nazwie klasy, nie mogę go uruchomić. Zauważam, że w tym przykładzie nie ma miejsca. Czy to możliwe?
Adamarla
@Adamarla <p class="foo bar">dodaje do pelementu dwie klasy : fooi bar. Nie ma sposobu (o czym myślę), aby dodać nazwę klasy zawierającą białe znaki do elementu HTML. Dołączono informacje o tym, jak uciec od znaków białych znaków, ponieważ warto uciec od takich znaków w innych kontekstach identyfikacyjnych, np. Nazwach czcionek.
Mathias Bynens,
3
Podobnie jak w przypadku większości rzeczy w życiu, w CSS wydaje się, że istnieje różnica między „technicznie legalnym a ekstremalnym” i „zdrowym rozsądkiem”.
Volksman
69

Przeczytaj specyfikację W3C . (jest to CSS 2.1, znajdź odpowiednią wersję dla twojego założenia przeglądarki)

edycja: odpowiedni akapit poniżej:

W CSS identyfikatory (w tym nazwy elementów, klasy i identyfikatory w selektorach) mogą zawierać tylko znaki [a-z0-9] i ISO 10646 znaków U + 00A1 i wyższe, a także łącznik (-) i podkreślenie (_) ; nie mogą zaczynać się cyfrą ani myślnikiem, po którym następuje cyfra. Identyfikatory mogą także zawierać znaki zmiany znaczenia i dowolny znak ISO 10646 jako kod numeryczny (patrz następny punkt). Na przykład identyfikator „B&W?” może być zapisane jako „B \ & W \?” lub „B \ 26 W \ 3F”.

edycja 2: jak @mipadi wskazuje w odpowiedzi Tryptyku, jest to zastrzeżenie , również na tej samej stronie:

W CSS identyfikatory mogą zaczynać się od „-” (myślnik) lub „_” (podkreślenie). Słowa kluczowe i nazwy właściwości zaczynające się od „-” lub „_” są zastrzeżone dla rozszerzeń specyficznych dla dostawcy. Takie rozszerzenia specyficzne dla dostawcy powinny mieć jeden z następujących formatów:

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

Przykłady:

Na przykład, jeśli organizacja XYZ dodała właściwość opisującą kolor obramowania po wschodniej stronie wyświetlacza, może nazwać to -xyz-border-east-color.

Inne znane przykłady:

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

Początkowej kreski lub podkreślenia nie gwarantuje się, że zostanie ona użyta we właściwości lub słowie kluczowym przez jakikolwiek obecny lub przyszły poziom CSS. Dlatego typowe implementacje CSS mogą nie rozpoznawać takich właściwości i mogą je ignorować zgodnie z zasadami obsługi błędów parsowania. Ponieważ jednak początkowy myślnik lub znak podkreślenia jest częścią gramatyki, implementatorzy CSS 2.1 powinni zawsze mieć możliwość korzystania z parsera zgodnego z CSS, niezależnie od tego, czy obsługują rozszerzenia specyficzne dla producenta.

Autorzy powinni unikać rozszerzeń specyficznych dla dostawcy

Jason S.
źródło
Miałem na myśli twoją drugą edycję o wiodących myślnikach i podkreśleniach, ale zapomniałem to wyjaśnić. Przepraszam za zamieszanie.
Albin
24

Pełne wyrażenie regularne to:

-?(?:[_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])*

Dlatego wszystkie wymienione na liście postacie oprócz „ -” i „ _” nie są dozwolone, jeśli zostaną użyte bezpośrednio. Ale możesz je zakodować za pomocą odwrotnego ukośnika foo\~barlub notacji Unicode foo\7E bar.

Gumbo
źródło
dlaczego [\200-\377]? [\178-\1114112]w CSS 3 jest dozwolony bez ucieczki
latające owce
\377tutaj jest właściwie źle. W sekcji gramatyki skanera leksykalnego CSS2.1 znajduje się uwaga: „„ \ 377 ”reprezentuje najwyższą liczbę znaków, z którą mogą sobie poradzić obecne wersje Flex (liczba dziesiętna 255). Należy ją odczytać jako„ \ 4177777 ”( dziesiętny 1114111), który jest najwyższym możliwym punktem kodowym w Unicode / ISO-10646. ” To też powinno być z \240, nie \377. Wydaje mi się, że ma teraz 7 lat, więc od tego czasu prawdopodobnie coś się zmieniło.
James Donnelly,
1
Wierzę, że byłoby bardziej dokładne wyrażenie regularne -?(?:[_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 Edytuj moją odpowiedź, jeśli uważasz, że wymaga aktualizacji.
Gumbo,
11

Dla tych, którzy szukają obejścia, możesz użyć selektora atrybutów, na przykład, jeśli twoja klasa zaczyna się od liczby. Zmiana:

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

do tego:

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

Ponadto, jeśli istnieje wiele klas, musisz je określić w selektorze.

Źródła:

  1. https://benfrain.com/when-and-where-you-can-use-numbers-in-id-and-class-names/
  2. Czy istnieje sposób obejścia problemu, aby klasy CSS o nazwach rozpoczynających się od liczb były prawidłowe?
D.Tate
źródło
5

Rozumiem, że podkreślenie jest technicznie ważne. Sprawdzić:

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

„... błędna specyfikacja opublikowana na początku 2001 roku po raz pierwszy uczyniła podkreślenia legalnymi”.

Artykuł, do którego prowadzi link powyżej, mówi, że nigdy ich nie używaj, a następnie podaje listę przeglądarek, które ich nie obsługują, a wszystkie z nich są co najmniej długo zbędne.

mofaha
źródło
4

W przypadku HTML5 / CSS3 klasy i identyfikatory mogą zaczynać się cyframi.

Marius
źródło
1
Czy masz na to źródło? Może czegoś mi brakuje, ale selektory CSS3 podają linki do definicji identyfikatorów w specyfikacji CSS 2.1, która nie zezwala na liczby wiodące.
Ryan
11
w3.org/TR/2003/WD-css3-syntax-20030813/#characters <- nadal nie zezwala na wiodące liczby itp. (nawet jeśli działa)
Jamie Pate
10
HTML 5 pozwala klasom i identyfikatorom zaczynać od liczby (np class="1a".). Jednak identyfikator CSS nie może zaczynać się od cyfry (np. .1aNie działa). Możesz uciec, trudny (np. .\31 aLub .\000031a).
Oriol
Chociaż normalnie działa również w CSS, ale wygląda na to, że nadal nie jest oficjalny. „Nazwy właściwości i nazwy reguł są zawsze identyfikatorami, które muszą zaczynać się od litery lub łącznika, po której następuje litera, a następnie mogą zawierać litery, cyfry, łączniki lub znaki podkreślenia”. - w3.org/TR/css3-syntax/#syntax-description
Naklejki
@Pangloss Ale nazwy klas nie są nazwami własności ani nazwami reguł.
Bennett McElwee
1

Wychodząc z odpowiedzi @ Triptych, możesz użyć następujących 2 dopasowań wyrażeń regularnych, aby łańcuch był prawidłowy:

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

Jest to odwrotne dopasowanie, które wybiera wszystko, co nie jest literą, cyfrą, myślnikiem ani podkreśleniem, dla łatwego usunięcia.

^-*[0-9]+

Dopasowuje 0 lub 1 myślniki, a następnie 1 lub więcej liczb na początku łańcucha, również w celu łatwego usunięcia.

Jak go używać w PHP:

//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
źródło