我读HTML 4.01标准错了,还是谷歌?在HTML 4.01中,如果我写:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html> <head> <body>plain <em>+em <strong>+strong </em>-em
Run Code Online (Sandbox Code Playgroud)
Google Chrome中的呈现是:
普通+ em + 强 - em
这似乎违背了HTML 4.01标准,总结了下面的SGML规则为:"结束标记关闭,返回到匹配的开始标记,省略结束标记所有未关闭的中介开始标记".¹
也就是说,</em>结束标记不仅应该关闭<em>开始标记,还应该关闭未关闭的插入<strong>开始标记,并且渲染应该是:
普通+ em + 强 - em
一位意见提供者指出,将标签打开是不好的做法,但这只是一个学术性的例子.一个同样好的例子是:<em> +em <strong> +strong </em> -em </strong>.根据HTML 4.01标准我的理解是,由于重叠元素,此代码片段无法按预期工作:</em>结束标记应隐式关闭<strong>.它确实按预期工作的事实令人惊讶,这就是我的问题所在.
事实证明我在这个问题中提出了一个错误的二分法:谷歌和我都没有读错HTML 4.01标准.w3.org的一位私人记者向我指出了Web SGML和HTML 4.0由Martin Bryan解释,他解释说"解析程序将自动关闭任何当前打开的嵌入式元素,当前它被声明为具有可省略的结束标记.遇到更高级别元素的结束标记.(如果无法省略其结束标记的嵌入式元素仍然打开,则程序将报告编码中的错误.)" ²(强调添加.)Bryan对SGML标准的总结是正确的,并且HTML 4.01的总结是错误的.
允许省略某些标记(例如结束标记<p>或开始和结束标记<body>),而有些标记不是(例如结束标记<strong>).前者是您引用的规范部分所指的.您可以通过在DTD中使用破折号来识别它们:
<!ELEMENT P - O (%inline;)* -- paragraph -->
^A p element
^ requires a start tag
^ has optional end tag
^ contains zero or more inline things
^ Comment: Is a paragraph
Run Code Online (Sandbox Code Playgroud)
你所拥有的不是带有省略标记的HTML文档,而是浏览器将尝试执行错误恢复的无效伪HTML文档.
规范(适用于HTML 4)没有描述如何执行错误恢复,这是由浏览器决定的.
引用自 HTML 4.01 规范的声明非常晦涩,或者从所有角度来看都是完全错误的。HTML 4.01 对于结束标记省略有特定的规则,这些规则取决于元素。例如,p元素的结束标签可以被省略,而 an 的结束标签em可能永远不会被省略。规范中的声明可能试图说结束标记隐式地关闭任何尚未关闭的内部元素,在允许省略结束标记的范围内。
没有浏览器按照定义实现 HTML 4.01(或任何早期的 HTML 规范),并且 SGML 功能正式成为其中的一部分。HTML 规范中关于 SGML 的任何内容都应该被视为理论上的,除非另有证明。
\nHTML5在这方面并没有改变游戏规则,只不过它写下了错误处理规则。在诸如此类的简单问题中,规则只是使传统的浏览器行为成为一种规范。它们是面向 tagoup 的,或多或少将某些<em>标签视为格式化命令:表示 \xe2\x80\x9citalicize,\xe2\x80\x9d</em>表示 \xe2\x80\x9cstop italicizing,\xe2\x80\x9d 等。但 HTML5 也采取措施更正式地定义错误处理,以便尽管使用了这样的标签汤,但可以明确定义将在 DOM 中构建什么文档树。