Quais caracteres são válidos nos nomes / seletores de classe CSS?

1203

Quais caracteres / símbolos são permitidos nos seletores de classe CSS ?
Sei que os seguintes caracteres são inválidos , mas que caracteres são válidos ?

~ ! @ $ % ^ & * ( ) + = , . / ' ; : " ? > < [ ] \ { } | ` #
Darryl Hein
fonte
5
Pergunta relacionada: stackoverflow.com/questions/2812072/…
BalusC:
32
e quanto aos caracteres utf8? Como eu pode digitar em grego
GorillaApe
9
Caracteres especiais podem ser usados em nomes de classe, escapando-los - em seu arquivo CSS você pode definir uma .hello/worldclasse por escapar a barra invertida: .hello\2fworld, hello\2f worldouhello\/world
wyqydsyq
1
Outra questão relacionada, não sobre "sintaxe de nomes", mas sobre "sintaxe de atributo de classe" ao expressar vários nomes .
Peter Krauss
2
Você também pode usar emoji. npmjs.com/package/postcss-modules-emoji-classname
Kevin Suttle

Respostas:

1024

Você pode verificar diretamente na gramática CSS .

Basicamente 1 , um nome deve começar com um sublinhado ( _), um hífen ( -) ou uma letra ( a- z), seguido por qualquer número de hífens, sublinhados, letras ou números. Existe um problema: se o primeiro caractere é um hífen, o segundo caractere deve ser 2 uma letra ou sublinhado e o nome deve ter pelo menos 2 caracteres.

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

Em resumo, a regra anterior se traduz no seguinte, extraída da especificação do W3C. :

No CSS, os identificadores (incluindo nomes de elementos, classes e IDs nos seletores) podem conter apenas os caracteres [a-z0-9] e os caracteres ISO 10646 U + 00A1 e superior, além do hífen (-) e o sublinhado (_) ; eles não podem começar com um dígito ou um hífen seguido por um dígito. Os identificadores também podem conter caracteres de escape e qualquer caractere ISO 10646 como um código numérico (consulte o próximo item). Por exemplo, o identificador "P&B?" pode ser escrito como "B \ & W \?" ou "B \ 26 W \ 3F".

Identificadores começando com um hífen ou sublinhado são normalmente reservados para extensões específicas do navegador, como em -moz-opacity.

1 Tudo ficou um pouco mais complicado com a inclusão de caracteres unicode escapados (que ninguém realmente usa).

2 Observe que, de acordo com a gramática que eu vinculei, uma regra começando com DOIS hífens, por exemplo --indent1, é inválida. No entanto, tenho certeza que já vi isso na prática.

Tríptico
fonte
57
Nota: O W3C diz que o uso de um '-' ou '_' importante deve ser reservado para extensões CSS específicas do fornecedor (por exemplo, classes -moz * implementadas pelos navegadores Mozilla).
Mipadi
3
Os \ -escapes são comumente usados, mas geralmente para fins de hacks CSS, isolando navegadores que não os suportam.
bobince
5
Para atualizar o comentário do @Pim Jager mais de dois anos depois, de acordo com o w3counter.com/globalstats.php, o IE6 agora é usado por menos de 3% dos usuários, atrás do IE9 em 4%, do IE7 em 9% e do IE8 em 22%. Todas as versões do Firefox possuem 28%, todas as versões do Chrome possuem 17%.
Daniel Earwicker
3
Sei que essa é uma resposta antiga, mas o CSS (pelo menos 2 ou mais) permite qualquer caractere {Não ASCII} nos identificadores.
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". Então - --indent1é inválido e precisa ser escapado como \--indent1(as --classes quebram no iOS, por exemplo)
eithed
177

Para minha surpresa, a maioria das respostas aqui estão erradas. Acontece que:

Qualquer caractere, exceto NUL, é permitido nos nomes de classe CSS em CSS. (Se o CSS contiver NUL (escapado ou não), o resultado será indefinido. [ CSS-caracteres ])

A resposta de Mathias Bynens tem links para explicações e demos mostrando como usar esses nomes. Escrito em código CSS, um nome de classe pode precisar ser escapado , mas isso não altera o nome da classe. Por exemplo, uma representação desnecessariamente excedida em escape parecerá diferente de outras representações com esse nome, mas ainda se refere ao mesmo nome de classe.

A maioria das outras linguagens (de programação) não tem esse conceito de escapar nomes de variáveis ​​(“identificadores”), portanto, todas as representações de uma variável devem ter a mesma aparência. Este não é o caso em CSS.

Observe que, no HTML, não há como incluir caracteres de espaço (espaço, tabulação, avanço de linha, avanço de formulário e retorno de carro) em um atributo de nome de classe , porque eles já separam as classes.

Portanto, se você precisar transformar uma sequência aleatória em um nome de classe CSS: cuide de NUL e espaço e escape (de acordo com CSS ou HTML). Feito.

Robert Siemer
fonte
7
A primeira linha da sua resposta deve ser "a maioria das respostas aqui está desatualizada / aplica-se apenas ao CSS2".
Salman Um
7
@SalmanA As respostas às quais me refiro estavam erradas desde o início. Eles não se aplicam ao CSS2.1, CSS2 nem CSS1.
Robert Siemer
@RobertSiemer ponto bom, eu mudei o meu comentário a stackoverflow.com/questions/50812118/... (que é nunca a menos relacionadas a este tópico)
Peter T.
E implementação de JavaScript: github.com/mathiasbynens/CSS.escape/blob/master/css.escape.js
Duarte Cunha Leão
71

Respondi a sua pergunta em profundidade aqui: http://mathiasbynens.be/notes/css-escapes

O artigo também explica como escapar de qualquer caractere em CSS (e JavaScript), e eu fiz uma ferramenta útil para isso também. A partir dessa página:

Se você der um valor de ID a um elemento ~!@$%^&*()_+-=,./';:"?><[]{}|`#, o seletor ficará assim:

CSS:

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

JavaScript:

<script>
  // document.getElementById or similar
  document.getElementById('~!@$%^&*()_+-=,./\';:"?><[]\\{}|`#');
  // document.querySelector or similar
  $('#\\~\\!\\@\\$\\%\\^\\&\\*\\(\\)\\_\\+-\\=\\,\\.\\/\\\'\\;\\:\\"\\?\\>\\<\\[\\]\\\\\\{\\}\\|\\`\\#');
</script>
Mathias Bynens
fonte
4
@ Darryl Claro, este é um exemplo bastante extremo, mas coisas como class="404-error"podem ser úteis.
Mathias Bynens
Eu tenho um exemplo: eu converto uma saída do sistema de destaque de sintaxe para CSS. possui nomes de classe como "ISO C ++: Tipos ( _t / _type)". se eu substituir apenas espaço em branco, tenho nomes de classe válidos.
ovelha voadora
No seu site, você diz que o caractere de espaço pode ter uma barra invertida. Quando o tento em um nome de classe, não consigo fazê-lo funcionar. Percebo que não há espaço neste exemplo. É possível?
Adamarla
O @Adamarla <p class="foo bar">adiciona duas classes ao pelemento :, fooe bar. Não há como (em que eu possa pensar) adicionar um nome de classe contendo espaço em branco a um elemento HTML. As informações sobre como escapar caracteres em branco foram incluídas porque é útil escapar desses caracteres em outros contextos identificadores, por exemplo, nomes de família de fontes.
Mathias Bynens
3
Como na maioria das coisas na vida, parece que no CSS existe uma diferença entre "tecnicamente legal ao extremo" e "sã".
Volksman
69

Leia a especificação do W3C . (isto é CSS 2.1, encontre a versão apropriada para sua suposição de navegadores)

editar: parágrafo relevante a seguir:

No CSS, os identificadores (incluindo nomes de elementos, classes e IDs nos seletores) podem conter apenas os caracteres [a-z0-9] e os caracteres ISO 10646 U + 00A1 e superior, além do hífen (-) e o sublinhado (_) ; eles não podem começar com um dígito ou um hífen seguido por um dígito. Os identificadores também podem conter caracteres de escape e qualquer caractere ISO 10646 como um código numérico (consulte o próximo item). Por exemplo, o identificador "P&B?" pode ser escrito como "B \ & W \?" ou "B \ 26 W \ 3F".

edit 2: como o @mipadi aponta na resposta do Triptych, há essa ressalva , também na mesma página da web:

No CSS, os identificadores podem começar com '-' (traço) ou '_' (sublinhado). Palavras-chave e nomes de propriedades que começam com '-' ou '_' são reservados para extensões específicas do fornecedor. Essas extensões específicas do fornecedor devem ter um dos seguintes formatos:

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

Exemplos):

Por exemplo, se a organização XYZ adicionou uma propriedade para descrever a cor da borda no lado leste da tela, eles podem chamá-la de -xyz-border-east-color.

Outros exemplos conhecidos:

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

Um traço ou sublinhado inicial é garantido para nunca ser usado em uma propriedade ou palavra-chave por qualquer nível atual ou futuro de CSS. Assim, implementações CSS típicas podem não reconhecer essas propriedades e podem ignorá-las de acordo com as regras para manipulação de erros de análise. No entanto, como o traço ou sublinhado inicial faz parte da gramática, os implementadores do CSS 2.1 sempre devem poder usar um analisador em conformidade com o CSS, independentemente de suportar ou não extensões específicas do fornecedor.

Os autores devem evitar extensões específicas do fornecedor

Jason S
fonte
Eu estava me referindo à sua segunda edição sobre traços e sublinhados principais, mas esqueci de esclarecer isso. Desculpe pela confusão.
Albin
24

A expressão regular completa é:

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

Portanto, todos os seus personagens listados, exceto “ -” e “ _”, não são permitidos se usados ​​diretamente. Mas você pode codificá-los usando uma barra invertida foo\~barou usando a notação unicode foo\7E bar.

quiabo
fonte
por que [\200-\377]? [\178-\1114112]é permitido sem escape no CSS 3.
flying sheep o
\377aqui está realmente errado. Há uma observação na seção Gramática do Scanner Lexical do CSS2.1, que afirma: "O" \ 377 "representa o número de caractere mais alto com o qual as versões atuais do Flex podem lidar (decimal 255). Ele deve ser lido como" \ 4177777 "( decimal 1114111), que é o ponto de código mais alto possível em Unicode / ISO-10646. " Também deve ser \240também, não \377. Eu acho que agora tem 7 anos, então as coisas provavelmente mudaram um pouco desde então.
James Donnelly
1
Acredito que uma expressão regular mais precisa seria -?(?:[_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 Sinta-se livre para editar minha resposta, se você acha que precisa de alguma atualização.
Gumbo
11

Para quem procura uma solução alternativa, você pode usar um seletor de atributos, por exemplo, se sua classe começar com um número. Mudança:

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

para isso:

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

Além disso, se houver várias classes, você precisará especificá-las no seletor, eu acho.

Fontes:

  1. https://benfrain.com/when-and-where-you-can-use-numbers-in-id-and-class-names/
  2. Existe uma solução alternativa para tornar válidas as classes CSS com nomes que começam com números?
D.Tate
fonte
5

Meu entendimento é que o sublinhado é tecnicamente válido. Verificação de saída:

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

"... erratas às especificações publicadas no início de 2001 tornaram os sublinhados legais pela primeira vez."

O artigo vinculado acima diz que nunca os utiliza e, em seguida, fornece uma lista de navegadores que não os suportam, os quais são, em termos de número de usuários, pelo menos, redundantes.

mofaha
fonte
4

Para HTML5 / CSS3, as classes e os IDs podem começar com números.

Marius
fonte
1
Você tem uma fonte para isso? Talvez esteja faltando alguma coisa, mas os seletores CSS3 especificam links para a definição de identificadores na especificação CSS 2.1, que não permite números iniciais.
Ryan
11
w3.org/TR/2003/WD-css3-syntax-20030813/#characters <- continua a não permitir que conduz números etc (mesmo que ele funciona)
Jamie Pate
10
O HTML 5 permite que classes e IDs comecem com um número (por exemplo class="1a"). No entanto, um identificador CSS não pode começar com um número (por exemplo .1a, não funcionará). Você pode escapar, difícil (por exemplo, .\31 aou .\000031a).
Oriol
Embora normalmente também funcione em CSS, parece que ainda não é oficial. "Os nomes de propriedades e os nomes de regra são sempre identificadores, que precisam começar com uma letra ou um hífen seguido por uma letra e podem conter letras, números, hífens ou sublinhados." - w3.org/TR/css3-syntax/#syntax-description
Adesivos
@ Pangloss Mas nomes de classes não são nomes de propriedades ou nomes de regras.
Bennett McElwee
1

Ao sair da resposta do @ Triptych, você pode usar as 2 correspondências de regex a seguir para validar uma string:

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

Esta é uma correspondência inversa que seleciona qualquer coisa que não seja uma letra, número, traço ou sublinhado para facilitar a remoção.

^-*[0-9]+

Corresponde a 0 ou 1 traços seguidos por 1 ou mais números no início de uma sequência, também para facilitar a remoção.

Como eu o uso no 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
fonte