我正在考虑编写代码,生成一个可能包含重复属性的HTML标签,如下所示:
<div data-foo="bar" class="some-class" data-foo="baz">
这是否是合法的HTML?data-foo
中的一个值是否比另一个更优先?我能否相信半现代的浏览器(IE >= 9)在解析它时不会出问题?
还是说我要做某些非常愚蠢的事情?
我正在考虑编写代码,生成一个可能包含重复属性的HTML标签,如下所示:
<div data-foo="bar" class="some-class" data-foo="baz">
这是否是合法的HTML?data-foo
中的一个值是否比另一个更优先?我能否相信半现代的浏览器(IE >= 9)在解析它时不会出问题?
还是说我要做某些非常愚蠢的事情?
在一个元素中重复使用相同的属性名称是无效的。这方面的权威参考资料有些复杂,因为旧版的HTML名义上是基于SGML的,而该限制是通过一项对SGML标准的规范引用来暗示的。在HTML5 PR第8.1.2.3节Attributes中明确表示:“在同一个起始标记上永远不应有两个或更多属性具有ASCII大小写不敏感匹配的名称。”
实际上,后面的属性将被忽略。未来的浏览器可能会做出不同的处理。在DOM中,属性出现为元素节点的属性以及在attributes
对象中,因此没有自然的方法来存储两个值。
虽然不符合技术规范,但在 HTML 文档中重复使用属性,每个浏览器都会忽略,并使用第一个值 (data-foo="bar"
在这里指的是)。
在标签中两次使用同一属性名被认为是内部解析错误。如果你担心这种情况导致文档无法验证,则文档将验证失败。但是,重要的是要理解,即使出现“解析错误”,HTML5 也为此定义了预期结果。解析器有权在遇到错误时停止,但如果它选择不停止,则必须生成规范中描述的特定结果。实际上,没有浏览器会在处理 HTML 文档时停止遇到错误 (XML/XHTML 是另一回事),因此所有现代浏览器都可以成功而一致地处理这种情况。
WHATWG HTML 规范在第 12.2.4.33 节 "Attribute name state" 中描述了此情况:
当用户代理离开属性名称状态(并在适当时发出标记令牌之前),必须将完整属性的名称与同一令牌上的其他属性进行比较;如果令牌上已经有与完全相同名称的属性,则这是一个解析错误,新属性必须被删除,以及与其相关联的值(如果有)。
此外,还可以从第 12.2 节 "解析 HTML 文档" 的开头查看“解析错误”的描述:
某些情况下的解析算法被称为解析错误。对于解析错误的错误处理已定义良好(这是在本规范中描述的处理规则),但 用户代理在解析 HTML 文档时,可能会在遇到第一个不打算应用本规范中所述规则的解析错误时中止解析器。
我希望添加一条评论到优秀答案下面,但我的声誉值不够。
重要的是需要考虑你的代码如何被编译。比如说,Angular会删除多余的(非Angular)class
属性,并且只保留最后一个。
注意:Angular也会通过ngClass
和任何[class.class-name]
属性来修改class属性的值。
这也是可以使用linter工具的一个地方。
可以查看htmlhint (attr-no-duplication) 或者 htmllint (attr-no-dup)。