HTML属性名允许使用哪些字符?

89
在HTML属性中name=value对中,'name'部分允许使用哪些字符? .....查看一些常见属性,似乎只有字母(a-z和A-Z)被使用,但是还有哪些字符可以被允许使用呢?...也许数字(0-9)、连字符(-)和句点(.)等字符也可以被允许使用... 是否有规范来说明这一点?

2
这听起来像是引发Angular 2的问题 :P - Matt Lyons-Wood
5个回答

67

这取决于你所说的“允许”。每个标签都有一个固定的属性名称列表是有效的,而在HTML中它们是不区分大小写的。从一个重要的意义上来说,“允许”的仅仅是这些字符以正确的顺序。

另一种看待它的方式是,浏览器将处理哪些字符作为有效的属性名称。最好的建议来自HTML 5的解析器规范,可以在此处找到:https://html.spec.whatwg.org/multipage/syntax.html#attributes-2

它说除了制表符、换行符、换页符、空格、斜杠、大于号、引号、撇号和等于号之外的所有字符都将被视为属性名称的一部分。个人而言,我不会尝试推动这些边缘情况。


7
回答我的问题。“除了……之外的所有字符都将被视为属性名的一部分”——很高兴你能在规范中找到这个信息! - Robin Rodricks
34
参考正则表达式为/([^\t\n\f \/>"'=]+)/,需要将其翻译为通俗易懂的中文。 - Nate
9
“每个标签都有一份固定的有效属性名称列表”——除非该标签是自定义元素,那么您可以自己定义属性。 - tomekwi
4
给程序员小提示:如果你的属性名是data-foo,在 JavaScript 中使用MyElem.data-foo;会出现问题。请改为使用MyElem.getAttribute("data-foo"); - manuell
2
@manuell 不,MyElem.dataFoo 很好用。破折号的条目会自动转换为驼峰命名法的条目。 - PRMan
显示剩余11条评论

37
自从这个问题被提出来以后,网络已经发展了很多。很可能Web组件(自定义元素)的作者正在尝试学习在自定义元素上定义属性时可以使用哪些有效名称。
这里有几个部分正确的答案,所以我将尝试汇总它们并根据最近的规范进行更新。
首先,在HTML5中,属性名称可以以大多数字符开头,并且比HTML的先前版本更加宽容。@S.Lott的答案对于HTML 2和XHTML是正确的,但对于HTML5则不是。
对于HTML5:(spec)
属性名称必须由一个或多个字符组成,除空格字符、U+0000 NULL、U+0022引号(“)、U+0027撇号(')、U+003E大于号(>)、U+002F斜杠(/)和U+003D等号(=)字符、控制字符以及任何未被Unicode定义的字符之外。在HTML语法中,属性名称,即使是用于外部元素的属性名称,也可以写成任何大小写字母的混合体,这些字母与属性名称的ASCII大小写不敏感匹配。
话虽如此,这里的其他评论者是正确的,当在内置元素上使用不在其有效属性列表中的属性时,你技术上违反了规范。然而,浏览器作者对此有很高的容忍度,因此实际上并没有(太多?)害处。许多库利用这一点来增强常规HTML标记,这会导致一些混淆,因为它在技术上不是有效的HTML。HTML5提供了一种通过使用data-属性命名约定在属性中自定义数据的机制。
这些规则对于自定义元素来说是不同的。
自定义元素作者可以为其元素实现任何类型的属性,但属性名称比HTML5更加严格。事实上,规范要求属性名称遵循XML名称限制:
ASCII符号和标点符号以及一些Unicode符号字符被排除在名称之外,因为它们在XML名称在XML文档之外的上下文中更有用作分隔符。提供此组使得这些上下文对XML名称的组成有了硬性保证。字符#x037E,希腊问号,被排除在外,因为当其规范化时会变成分号,这可能会改变实体引用的含义。
名称和标记 [4] NameStartChar :: = ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF] [4a] NameChar :: = NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040] [5] Name :: = NameStartChar(NameChar)* [6] Names :: = Name(#x20 Name)* [7] Nmtoken :: =(NameChar)+ [8] Nmtokens :: = Nmtoken(#x20 Nmtoken)*

因此,对于自定义元素名称,您可以使用大写/小写字母数字、下划线"_"、冒号":"或规范中指定的任何Unicode字符作为起始字符,然后使用破折号"-"、点"."、字母等作为主体字符。


2
干得好。在2022年,这仍然是最新的答案,应该显示在列表的顶部。两个来自2009年的答案超过了这个2018年的答案,这并不理想。 - Rounin

31

假设你谈论的是XHTML,那么XML规则适用。

请参见http://www.w3.org/TR/2008/REC-xml-20081126/#NT-Name

名称和标记

[4]     NameStartChar      ::=      ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
[4a]    NameChar       ::=      NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
[5]     Name       ::=      NameStartChar (NameChar)*
[6]     Names      ::=      Name (#x20 Name)*
[7]     Nmtoken    ::=      (NameChar)+
[8]     Nmtokens       ::=      Nmtoken (#x20 Nmtoken)*

顺便提一下,并不是所有这些规则在浏览器中都适用。尝试使用 document.body.setAttribute('\u1fff', 1) - 这将会出错。 - dy_

7
也许我漏掉了什么,但我认为这个问题是基于错误的假设。在HTML中,属性是严格按照固定规范定义的。如果你“编造”自己的属性名称,那么你就不再编写有效的HTML。

14
除非你正在创建自定义元素或使用data-*属性。 - leviathanbadger

0
允许的值在w3.org上列出。如果您添加自定义属性,那么您就不再编写HTML了。

最终的。因此,所有允许的字符都是该文档中存在的字符。谢谢! - Robin Rodricks
10
可以自定义data-属性,因此“那不完全是真的”。 - ioquatix
2
@ioquatix — 这在2009年是正确的!即使在数据属性混合的情况下,它也是规范中定义的一种非常特定的定制形式。 - Quentin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接