首先,h1
toh6
元素总是需要它们的开始和结束标签才能进行验证,甚至在 HTML 3.2 中也是如此:
H1
, H2
, H3
, H4
,H5
和H6
用于文档标题。您总是需要开始和结束标签。
因此,链接中的页面和您的示例均无效。
也就是说,有趣的是浏览器如何以不同的方式处理这两种情况(是的,未封闭<h3>
的标签是问题所在):
在任何 HTML DOM 中,h1
toh6
元素永远不能成为彼此的子元素,类似于p
元素永远不能成为彼此的子元素。任何直接跟在任何此类未关闭的开始标签之后的对标签的打开都会隐式关闭它,<h1>
并且只有. 因此,您示例中的所有元素实际上都是彼此的兄弟姐妹,而不是连续的后代。<h6>
h3
但是,该页面中发生的情况是h3
元素根本不是彼此的兄弟姐妹。相反,它们都由表格单元格、font
元素等分隔。这是一团糟(尽管这可能是使用 Microsoft FrontPage 1创作的页面所期望的)。
但是,虽然<tr>
和<td>
标签有自己的结束标签,但这不会导致<h3>
它们之间的标签隐式关闭。他们还开着!由于没有一个<h3>
标签是封闭的,并且有中间<font>
标签和其他标签与元素发生冲突h3
,结果是这些h3
元素包含所有它们作为后代的元素,但不直接作为子元素,尽管有and<tr>
元素<td>
:
h3
font
font
...
h3
font
font
...
结果,字体大小随着每个连续的 增加h3
,并且随之而来的是相当大的(哈哈!)灾难。请注意,这些font
元素是不相关的,因为它们都没有定义size
属性。
这一切的主要收获是什么?
验证你该死的标记。2特别是,关闭您所有的怪异标签(禁止关闭标签的地方除外)。
尽管页面和您的示例使用触发 quirks 模式的 HTML 3.2 doctype,但应注意此行为在 quirks 模式和标准模式中是一致的。事实上,HTML5 规范包含一个完全致力于解析和DOM 树构造的部分,以便针对无效标记设置各种浏览器行为(与旧标记兼容等)。即使在标准模式下,浏览器也应该遵循这个规范,因此在大多数浏览器中两种模式下的行为都是一致的。
其中有一个小节包含有关如何处理这种特定情况的规则:
一个起始标签,其标签名称是以下之一:“h1”、“h2”、“h3”、“h4”、“h5”、“h6”
如果打开元素的堆栈有一个p
按钮范围内的元素,那么就好像看到了一个标签名为“p”的结束标签。
如果当前节点是标签名称为“h1”、“h2”、“h3”、“h4”、“h5”或“h6”之一的元素,则这是一个解析错误;从打开的元素堆栈中弹出当前节点。
为令牌插入一个 HTML 元素。
这意味着如果解析器仅在当前打开的标题元素中遇到标题标签,则会引发解析错误,并且它应该在输入这个新的标题元素之前关闭先前打开的标题元素,这就是您的示例所发生的情况。否则,没有什么特别的事情发生(即解析器应该像往常一样继续)。
也就是说,请不要依赖这个。解析错误仍然是错误;善待解析器,不要仅仅因为可以就向它抛出错误。只需编写有效的代码就可以了。当然,即使在您验证了您的代码之后,如果浏览器仍然出现问题,您就可以担心了。
1 顺便说一句,这也是我的第一个 HTML 编辑器……我 9 岁。
2 不要过度,但也不要忽视去做。