为什么未闭合的H3标签会破坏这个页面?

12
如果你使用最新版本的Chrome、Firefox或IE现代浏览器查看这个页面(链接),你会发现文本变得更大了。查看源代码,似乎是由于代码中存在未关闭的<h3>标签导致的。
然而,我记得大多数浏览器都会在有机会时自动关闭标签。下面的代码(与出问题的网站具有相同的doctype)可以正常工作,所有标签都被正确关闭:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
  <head></head>
  <body>Hello
    <h3>My
    <h3>Name
    <h3>Is
    <h3>Manish
  </body>
</html>

因此,未关闭的<h3>标签可能不是问题的原因(或只是问题的一部分)。

所以,我的问题是,为什么浏览器不自动关闭这些标签呢?


12
你在问为什么无效的HTML无法正常工作? - Kevin Bowersox
http://www.brainyquote.com/quotes/quotes/c/charlesbab141832.html - ta.speot.is
6
@KevinBowersox:不,我是在问为什么这个神奇的无效HTML修复工具不起作用。 - Manishearth
字体(face)、背景颜色(bgcolor)等所有这些标签都是无效的。 - Chris
1
对于那些想知道的人,这是上面链接的存档版本:https://web.archive.org/web/20140310190221/http://www.sewingandembroiderywarehouse.com/embtrb.htm - Alex_M
显示剩余2条评论
3个回答

15

首先,h1h6这些元素一直需要它们的开始标签和结束标签才能进行验证,甚至在HTML 3.2中都是如此:

H1, H2, H3, H4, H5H6 用于文档标题。你总是需要开始和结束标签。

所以,链接页面和您的示例都是无效的。

话虽如此,有趣的是浏览器如何不同地处理两种情况(是的,未关闭的<h3>标签是问题):

在任何HTML DOM中,h1h6元素不能相互嵌套,就像p元素不能相互嵌套一样。直接跟随任何未关闭的开放标签的任何<h1><h6>标签将隐式关闭它,仅在此之后。因此,你的示例中所有h3元素实际上都是彼此的兄弟,而不是连续的后代。
然而,在该页面中发生的情况是,h3元素根本不是彼此的兄弟。相反,它们都被表格单元格、font元素等分隔开来。这是一团糟(尽管这可能是使用Microsoft FrontPage撰写的页面所期望的)。
然而,尽管<tr><td>标签有自己的闭合标签,但这并不会导致它们之间的<h3>标签隐式关闭。它们仍然是打开状态!由于没有一个<h3>标签被关闭,并且存在中间的<font>和其他标签与h3元素冲突,结果就是h3元素包含所有后续元素作为子代,但不是直接作为子元素,尽管有<tr><td>元素:
h3
  font
    font
      ...
        h3
         font
           font
             ...

作为结果,随着每个连续的 h3 的出现,字体大小会递增,从而导致了一个相当大的(哈!)灾难。请注意,font 元素是无关紧要的,因为它们中没有一个定义了 size 属性。
所有这些的主要收获是什么?
验证你的标记。特别是,关闭所有标记(除了禁止关闭标记的情况)。

虽然页面和您的示例使用HTML 3.2文档类型,触发了怪异模式,但应注意这种行为在怪异模式和标准模式下是一致的。事实上,HTML5规范包含一个完全专门用于解析DOM树构建的部分,以便铺平各种浏览器行为与无效标记相关的问题(与旧版标记兼容等)。预计浏览器甚至在标准模式下也将遵循此规范,因此在大多数浏览器中两种模式都具有一致性。

其中有一个子部分,包含处理此特定情况的规则:

如果正在打开一个标题元素时遇到另一个标题标签,则会抛出解析错误,并关闭先前打开的标题元素,然后再进入新的标题元素。如果没有打开任何标题元素,则继续正常解析。这意味着如果打开元素堆栈中有按钮范围内的p元素,则将其视为已看到标记名称为“p”的结束标记。插入令牌的HTML元素。
尽管如此,请不要依赖这个。解析错误仍然是一个错误;请友善地对待解析器,不要因为可以而向它抛出错误。只需编写有效的代码,您就会没问题。当然,如果浏览器即使在您验证了代码后仍然出现问题,那么您可以担心。

1顺便提一下,那也是我第一个HTML编辑器……我九岁。

2不要过度做,但也不要忽略它。


2
这甚至不是我第一次回答为什么浏览器以某种方式处理无效的HTML问题。 - BoltClock
2
虽然您的回答非常好,但我想补充一下为什么字体会变大(这也是我来到这里寻找答案的问题,可能其他人也是)。页面中字体大小随着向下滚动而增加是由于页面上使用了“em”字体大小单位,该单位相对于父元素的字体大小。由于所有h3标签都是嵌套的,因此字体大小会不断增加。(这也是我们今天有“rem”的原因,它相对于根字体大小) - niid

1

只有像<p><li>这样的特定标签是自动关闭的。 <hN>标签不是。

(此外,作为参考,如果一个网站在两个以上现代浏览器中出现问题,问题通常不在浏览器或规范上,而是在网站本身)。

无效的修正程序所能承受的惩罚是有限的。由于<font>元素是内联的(即使是无效的),<h3>不是直接子级(它不被认为是“同级”),因此没有理由让它在这些元素之外关闭<h3>,而且它们被包含在内。


2
重点是我在上面给出的示例代码中关闭了<h3>,为什么这里不起作用呢? - Manishearth
<hN>标签实际上可以自动关闭。请参见接受的答案中引用的HTML5规范(https://dev59.com/6WUq5IYBdhLWcg3wF8rw#14787315),以及问题中的简单示例。 - Inigo

-3

你总是需要关闭标题标签。从我所学到的来看,关闭 p 和 li 标签也是好的,尽管通常并不重要。编码的事情在于尽可能具体。你不希望浏览器去猜测任何东西,所以要具体。


3
我更想知道为什么未关闭的h3标签会破坏一个页面,但在另一个页面中它们被自动关闭了。(参见BoltClock的答案)。不用担心,我通常不会留下未关闭的标签。 - Manishearth

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