Какие символы допустимы в именах / селекторах классов CSS?

1203

Какие символы / символы разрешены в селекторах классов CSS ?
Я знаю, что следующие символы недопустимы , но какие символы допустимы ?

~ ! @ $ % ^ & * ( ) + = , . / ' ; : " ? > < [ ] \ { } | ` #
Дэррил Хейн
источник
5
Похожий вопрос: stackoverflow.com/questions/2812072/…
BalusC
32
что насчет символов utf8? Как я могу печатать на греческом
GorillaApe
9
Специальные символы могут использоваться в именах классов, убегая их - в файле CSS вы можете определить .hello/worldкласс, убегая обратную косую черту: .hello\2fworld, hello\2f worldилиhello\/world
wyqydsyq
1
Другой связанный вопрос, не о «синтаксисе имен», а о «синтаксисе атрибута класса» при выражении нескольких имен .
Питер Краусс
2
Вы также можете использовать эмодзи. npmjs.com/package/postcss-modules-emoji-classname
Кевин

Ответы:

1024

Вы можете проверить прямо в грамматике CSS .

В основном 1 , имя должно начинаться с символа подчеркивания ( _), дефиса ( -) или буквы ( a- z), за которым следует любое количество дефисов, символов подчеркивания, букв или цифр. Есть загвоздка: если первый символ является дефисом, второй символ должен быть 2 буквой или подчеркиванием, а имя должно быть длиной не менее 2 символов.

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

Короче говоря, предыдущее правило переводится в следующее, извлеченное из спецификации W3C. :

В CSS идентификаторы (включая имена элементов, классы и идентификаторы в селекторах) могут содержать только символы [a-z0-9] и символы ISO 10646 U + 00A1 и выше, плюс дефис (-) и знак подчеркивания (_) ; они не могут начинаться с цифры или с дефиса, за которым следует цифра. Идентификаторы также могут содержать экранированные символы и любые символы ISO 10646 в виде числового кода (см. Следующий пункт). Например, идентификатор "B & W?" может быть написано как "B \ & W \?" или "B \ 26 W \ 3F".

Идентификаторы, начинающиеся с дефиса или подчеркивания, обычно зарезервированы для специфичных для браузера расширений, как в -moz-opacity.

1 Все это немного усложняется включением экранированных символов Юникода (которые никто в действительности не использует).

2 Обратите внимание, что в соответствии с грамматикой, с которой я связан, правило, начинающееся с ДВУХ дефисов, например --indent1, является недействительным. Тем не менее, я уверен, что видел это на практике.

Триптих
источник
57
NB: W3C говорит, что использование начальных '-' или '_' должно быть зарезервировано для специфических для производителя расширений CSS (например, классов -moz *, реализованных браузерами Mozilla).
Мипади
3
\ -Escapes обычно используются, но обычно в основном для целей хаков CSS, изолируя браузеры, которые их не поддерживают.
бобинце
5
Чтобы обновить комментарий @Pim Jager через два года, согласно w3counter.com/globalstats.php, IE6 сейчас используется менее чем 3% пользователей, отставая от IE9 на 4%, IE7 на 9%, IE8 на 22%. Все версии Firefox имеют 28%, все версии Chrome имеют 17%.
Даниэль Уорвикер
3
Я знаю, что это старый ответ, но CSS (по крайней мере, 2+) допускает использование любого символа {не ASCII} в идентификаторах.
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", Так что - --indent1недействительно и должно быть экранированы , как \--indent1( --классы перерыв на прошивкой, например)
eithed
177

К моему удивлению, большинство ответов здесь неверны. Оказывается, что:

Любой символ, кроме NUL, допускается в именах классов CSS в CSS. (Если CSS содержит NUL (экранированный или нет), результат не определен. [ CSS-символы ])

Ответ Матиаса Биненса содержит ссылки на объяснения и демонстрации, показывающие, как использовать эти имена. Записанное в коде CSS, имя класса может нуждаться в экранировании , но это не меняет имя класса. Например, излишне избыточно экранированное представление будет отличаться от других представлений с таким именем, но оно все равно ссылается на то же имя класса.

Большинство других (программных) языков не имеют этой концепции экранирования имен переменных («идентификаторов»), поэтому все представления переменной должны выглядеть одинаково. Это не так в CSS.

Обратите внимание, что в HTML нет способа включить символы пробела (пробел, табуляцию, перевод строки, перевод формы и возврат каретки) в атрибут имени класса , поскольку они уже отделяют классы друг от друга.

Итак, если вам нужно превратить случайную строку в имя класса CSS: позаботьтесь о NUL и пробеле, и экранируйте (соответственно для CSS или HTML). Выполнено.

Роберт Симер
источник
7
Первая строка вашего ответа должна быть «большинство ответов здесь устарели / относятся только к CSS2».
Салман А
7
@SalmanA Ответы, на которые я ссылаюсь, были неправильными с самого начала. Они не применяются ни к CSS2.1, ни к CSS2, ни к CSS1.
Роберт Симер
@RobertSiemer Хорошая мысль, я переместил свой комментарий на stackoverflow.com/questions/50812118/… (который, тем не менее, связан с этой темой)
Питер Т.
И реализация JavaScript: github.com/mathiasbynens/CSS.escape/blob/master/css.escape.js
Дуарте Кунья Леан,
71

Я подробно ответил на ваш вопрос здесь: http://mathiasbynens.be/notes/css-escapes

В статье также объясняется, как избежать любого символа в CSS (и JavaScript), и я также создал удобный инструмент для этого. С этой страницы:

Если бы вы присвоили элементу значение идентификатора ~!@$%^&*()_+-=,./';:"?><[]{}|`#, селектор выглядел бы так:

CSS:

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

JavaScript:

<script>
  // document.getElementById or similar
  document.getElementById('~!@$%^&*()_+-=,./\';:"?><[]\\{}|`#');
  // document.querySelector or similar
  $('#\\~\\!\\@\\$\\%\\^\\&\\*\\(\\)\\_\\+-\\=\\,\\.\\/\\\'\\;\\:\\"\\?\\>\\<\\[\\]\\\\\\{\\}\\|\\`\\#');
</script>
Матиас Биненс
источник
4
@Darryl Конечно, это довольно экстремальный пример, но такие вещи class="404-error"могут быть полезны.
Матиас Биненс
у меня есть пример: я конвертирую вывод системы подсветки синтаксиса в CSS. у него есть имена классов, такие как «ISO C ++: Types ( _t / _type)». если я только заменяю пробел, у меня есть допустимые имена классов.
летающая овца
На вашем сайте вы говорите, что пробел может быть экранирован от обратной косой черты. Когда я пробую это в имени класса, я не могу заставить его работать. Я заметил, что в этом примере нет места. Является ли это возможным?
Адамарла
@Adamarla <p class="foo bar">добавляет два класса к pэлементу:, fooи bar. Нет способа (о котором я могу думать) добавить имя класса, содержащее пробел, к элементу HTML. Была включена информация о том, как экранировать пробельные символы, потому что полезно экранировать такие символы в других контекстах идентификаторов, например, в именах семейств шрифтов.
Матиас Биненс
3
Как и в большинстве вещей в жизни, в CSS кажется, что есть разница между «технически допустимым до крайности» и «вменяемым».
Volksman
69

Прочитайте спецификацию W3C . (это CSS 2.1, найдите подходящую версию для вашего браузера)

изменить: соответствующий абзац следующий:

В CSS идентификаторы (включая имена элементов, классы и идентификаторы в селекторах) могут содержать только символы [a-z0-9] и символы ISO 10646 U + 00A1 и выше, плюс дефис (-) и знак подчеркивания (_) ; они не могут начинаться с цифры или с дефиса, за которым следует цифра. Идентификаторы также могут содержать экранированные символы и любые символы ISO 10646 в виде числового кода (см. Следующий пункт). Например, идентификатор "B & W?" может быть написано как "B \ & W \?" или "B \ 26 W \ 3F".

изменить 2: как @mipadi указывает в ответе Триптиха, есть это предостережение , также на той же веб-странице:

В CSS идентификаторы могут начинаться с «-» (тире) или «_» (подчеркивание). Ключевые слова и имена свойств, начинающиеся с «-» или «_», зарезервированы для расширений, специфичных для поставщика. Такие специфичные для поставщика расширения должны иметь один из следующих форматов:

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

Примеры):

Например, если организация XYZ добавила свойство для описания цвета границы на восточной стороне экрана, они могли бы назвать его -xyz-border-east-color.

Другие известные примеры:

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

Гарантируется, что начальная черта или подчеркивание никогда не будут использоваться в свойстве или ключевом слове каким-либо текущим или будущим уровнем CSS. Таким образом, типичные реализации CSS могут не распознавать такие свойства и могут игнорировать их в соответствии с правилами обработки ошибок синтаксического анализа. Однако, поскольку начальная черта или подчеркивание является частью грамматики, разработчики CSS 2.1 всегда должны иметь возможность использовать CSS-совместимый синтаксический анализатор, независимо от того, поддерживают ли они какие-либо специфичные для поставщика расширения.

Авторы должны избегать специфичных для поставщика расширений

Джейсон С
источник
Я имел в виду ваше второе издание о ведущих черточках и подчеркиваниях, но забыл уточнить это. Извините за путаницу.
Альбин
24

Полное регулярное выражение:

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

Таким образом, все ваши перечисленные символы, кроме « -» и « _», не допускаются, если используются напрямую. Но вы можете закодировать их, используя обратную косую черту foo\~barили кодировку Unicode foo\7E bar.

гумбо
источник
почему [\200-\377]? [\178-\1114112]в CSS 3 разрешено не покинуть
летающая овца
\377здесь на самом деле не так. В грамматике раздела «Лексический сканер» CSS2.1 есть примечание: «\ 377» представляет наибольшее число символов, с которым могут работать текущие версии Flex (десятичное число 255.). Оно должно читаться как «\ 4177777» ( десятичное число 1114111), которое является максимально возможной кодовой точкой в ​​Unicode / ISO-10646. " Это также должно быть от, \240а не \377. Я полагаю, что сейчас 7 лет, хотя с тех пор ситуация, вероятно, немного изменилась.
Джеймс Доннелли
1
Я считаю, что более точное регулярное выражение будет -?(?:[_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])*.
Джеймс Доннелли
2
@JamesDonnelly Пожалуйста, не стесняйтесь редактировать мой ответ, если вы считаете, что требуется какое-то обновление.
Гамбо
11

Для тех, кто ищет обходной путь, вы можете использовать селектор атрибута, например, если ваш класс начинается с числа. Изменить:

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

к этому:

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

Кроме того, если есть несколько классов, вам нужно будет указать их в селекторе, я думаю.

Источники:

  1. https://benfrain.com/when-and-where-you-can-use-numbers-in-id-and-class-names/
  2. Есть ли обходной путь, чтобы сделать классы CSS с именами, которые начинаются с допустимых чисел?
D.Tate
источник
5

Насколько я понимаю, подчеркивание является технически обоснованным. Проверять, выписываться:

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

«... ошибки в спецификации, опубликованной в начале 2001 года, впервые подчеркнули законность».

В статье, приведенной выше, говорится, что никогда не используйте их, затем приведен список браузеров, которые их не поддерживают, и все они, по крайней мере с точки зрения количества пользователей, являются избыточными.

mofaha
источник
4

Для HTML5 / CSS3 классы и идентификаторы могут начинаться с цифр.

Marius
источник
1
У вас есть источник для этого? Может быть, я что-то упустил, но спецификация селекторов CSS3 ссылается на определение идентификаторов в спецификации CSS 2.1, которое не допускает начальные числа.
Райан
11
w3.org/TR/2003/WD-css3-syntax-20030813/#characters <- по-прежнему не разрешает ввод начальных чисел и т. д. (хотя это работает)
Джейми Пэйт,
10
HTML 5 позволяет классам и идентификаторам начинаться с цифры (например class="1a"). Однако идентификатор CSS не может начинаться с цифры (например .1a, не будет работать). Вы можете избежать этого, жестко (например, .\31 aили .\000031a).
Oriol
Хотя это обычно работает и в CSS, но, похоже, все еще не официально. «Имена свойств и имена в правилах всегда являются идентификаторами, которые должны начинаться с буквы или дефиса, за которыми следует буква, а затем могут содержать буквы, цифры, дефисы или подчеркивания». - w3.org/TR/css3-syntax/#syntax-description
Наклейки
@Pangloss Но имена классов не являются именами свойств или именами правил.
Беннет МакЭлви,
1

Исходя из ответа @ Triptych, вы можете использовать следующие 2 совпадения регулярных выражений, чтобы сделать строку допустимой:

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

Это обратное совпадение, при котором выбирается все, что не является буквой, цифрой, тире или подчеркиванием для легкого удаления.

^-*[0-9]+

Это соответствует 0 или 1 тире, за которыми следуют 1 или более цифр в начале строки, также для легкого удаления.

Как я использую это в 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 : '';
Мэнни Флермонд
источник