CSS类名称/选择器中哪些字符有效?


1202

CSS类选择器中允许使用哪些字符/符号?
我知道以下字符无效,但是哪些字符有效

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


32
utf8字符呢?就像我可以以希腊文
GorillaApe

9
特殊字符可以在类名由逃逸他们使用-在你的CSS文件,你可以定义一个.hello/world通过转义反斜线类:.hello\2fworldhello\2f worldhello\/world
wyqydsyq

1
另一个相关的问题,不是关于“名称的语法”,而是关于在表达多个名称时的“类属性的语法” 。
彼得·克劳斯

Answers:


1024

您可以直接在CSS语法中进行检查。

基本上,1,名称必须以下划线(_),连字符(-)或字母(az)开头,后跟任意数量的连字符,下划线,字母或数字。有一个陷阱:如果第一个字符是连字符,第二个字符必须2是字母或下划线,并且名称必须至少2个字符长。

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

简而言之,从W3C规范中提取的先前规则转化为以下规则。

在CSS中,标识符(包括选择器中的元素名称,类和ID)只能包含字符[a-z0-9]和ISO 10646字符U + 00A1及更高版本,以及连字符(-)和下划线(_) ; 它们不能以数字开头,也不能以连字符后接数字开头。标识符还可以包含转义字符和任何ISO 10646字符作为数字代码(请参阅下一项)。例如,标识符“ B&W?” 可以写为“ B \&W \?” 或“ B \ 26 W \ 3F”。

以连字符或下划线开头的标识符通常保留给特定于浏览器的扩展名,如中所述-moz-opacity

1由于包含转义的unicode字符(没有人真正使用过),这一切都变得更加复杂。

2请注意,根据我链接的语法,以两个连字符(例如)开头的规则--indent1无效。但是,我很确定我已经在实践中看到了这一点。


57
注意:W3C表示,应为供应商特定的CSS扩展(例如,由Mozilla浏览器实现的-moz *类)保留使用前导“-”或“ _”。
mipadi

3
\-转义符是常用的,但是通常主要是出于CSS hack的目的,将不支持它们的浏览器隔离开来。
bobince

5
根据w3counter.com/globalstats.php,要在两年后更新@Pim Jager的评论,IE6的使用率现在不到3%,仅次于IE9(4%),IE7(9%),IE8(22%)。Firefox的所有版本占28%,Chrome的所有版本占17%。
Daniel Earwicker 2011年

3
我知道这是一个旧答案,但是CSS(至少2+)允许标识符中包含任何{Non-ASCII}字符。
user2864740 2014年

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--类iOS上的突破,例如)
eithed

177

令我惊讶的是,这里的大多数答案都是错误的。事实证明:

CSS中的CSS类名称中允许使用除NUL之外的任何字符。(如果CSS包含NUL(是否转义了),则结果是不确定的。[ CSS字符 ])

Mathias Bynens的答案链接到说明演示演示了如何使用这些名称。写下来的CSS代码,类名可能需要逃避,但这并不改变类名。例如,不必要的过度转义的表示形式看起来将不同于该名称的其他表示形式,但它仍引用相同的类名称。

大多数其他(编程)语言都没有转义变量名称(“标识符”)的概念,因此变量的所有表示形式都必须看起来相同。CSS中不是这种情况。

请注意,在HTML中,无法在类名称属性中包含空格字符(空格,制表符,换行符,换页符和回车符),因为它们已经将各个类彼此分开。

因此,如果需要将随机字符串转换为CSS类名称:请注意NUL和空格,然后转义(对于CSS或HTML而言)。做完了


7
答案的第一行应为“此处大多数答案已过时/仅适用于CSS2”。
Salman A

7
@SalmanA我指的答案从一开始就是错误的。它们均不适用于CSS2.1,CSS2或CSS1。
罗伯特·西默

@RobertSiemer好点,我已将我的评论移至stackoverflow.com/questions/50812118/…(这与该主题的联系从未减少)
Peter T.


70

我已经在这里深入回答了您的问题:http : //mathiasbynens.be/notes/css-escapes

本文还介绍了如何在CSS(和JavaScript)中转义任何字符,为此我也做了一个方便的工具。从该页面:

如果要给元素ID值为~!@$%^&*()_+-=,./';:"?><[]{}|`#,则选择器将如下所示:

CSS:

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

JavaScript:

<script>
  // document.getElementById or similar
  document.getElementById('~!@$%^&*()_+-=,./\';:"?><[]\\{}|`#');
  // document.querySelector or similar
  $('#\\~\\!\\@\\$\\%\\^\\&\\*\\(\\)\\_\\+-\\=\\,\\.\\/\\\'\\;\\:\\"\\?\\>\\<\\[\\]\\\\\\{\\}\\|\\`\\#');
</script>

4
@Darryl当然,这是一个非常极端的示例,但是类似的东西class="404-error"可能会有用。
Mathias Bynens 2011年

我有一个例子:我将语法高亮系统的输出转换为CSS。它具有类似“ ISO C ++:Types(_t / _type)”的类名。如果我只替换空白,则我具有有效的类名。
飞羊

在您的网站上,您说空格字符可以反斜线转义。当我以班级名称尝试时,我无法使其正常工作。我注意到此示例中没有空间。可能吗?
Adamarla '16

@Adamarla <p class="foo bar">p元素添加了两个类:foobar。(我能想到的)没有办法向HTML元素添加包含空格的类名。包含有关如何转义空白字符的信息,因为在其他标识符上下文(例如字体系列名称)中转义此类字符很有用。
Mathias Bynens

3
与生活中的大多数事物一样,在CSS中似乎“技术上的极端”和“理智的”之间存在区别。
大众1998年

69

阅读W3C规范。(这是CSS 2.1,找到适合您的浏览器的版本)

编辑:相关段落如下:

在CSS中,标识符(包括选择器中的元素名称,类和ID)只能包含字符[a-z0-9]和ISO 10646字符U + 00A1及更高版本,以及连字符(-)和下划线(_) ; 它们不能以数字开头,也不能以连字符后接数字开头。标识符还可以包含转义字符和任何ISO 10646字符作为数字代码(请参阅下一项)。例如,标识符“ B&W?” 可以写为“ B \&W \?” 或“ B \ 26 W \ 3F”。

编辑2:正如@mipadi在Triptych的答案中指出的,在同一网页中也有此警告

在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的解析器,无论它们是否支持任何特定于供应商的扩展。

作者应避免特定于供应商的扩展


我指的是您关于前导破折号和下划线的第二种编辑方式,但忘了澄清一下。对困惑感到抱歉。
2015年

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的Lexical Scanner的语法部分有一个注释,其中指出:“” \ 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])*
James Donnelly

2
@JamesDonnelly如果您认为需要更新,请随时编辑我的答案。
Gumbo

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类有效?


4

对于HTML5 / CSS3,类和ID可以以数字开头。


1
你有这个来源吗?也许我错过了一些东西,但是CSS3选择器规范链接到CSS 2.1规范中的标识符定义,不允许使用前导数字。
瑞安

11
w3.org/TR/2003/WD-css3-syntax-20030813/#characters <-仍然不允许前导数字等(即使它可以工作)
Jamie Pate

10
HTML 5允许类和ID以数字开头(例如class="1a")。但是,CSS标识符不能以数字开头(例如,.1a将不起作用)。您可以逃脱它(例如.\31 a.\000031a)。
Oriol 2015年

尽管它通常也可以在CSS中使用,但是看起来它仍然不是官方的。“属性名称和规则名称始终是标识符,必须以字母或连字符开头,后跟字母,然后可以包含字母,数字,连字符或下划线。” - w3.org/TR/css3-syntax/#syntax-description
贴纸

@Pangloss但是类名称不是属性名称或规则名称。
Bennett McElwee

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 : '';
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.