以下内容转载自方应杭的博客
无内容元素(Void elements)
无内容元素是一种不能包含任何内容的特殊元素。而其他元素,比如 <div>
,则既可以不包含任何内容,又可以包含另一个元素或者文字。
比较常见的无内容元素有:
<br>
<hr>
<img>
<input>
<link>
<meta>
不太常见的无内容元素有:
<area>
<base>
<col>
<command>
<embed>
<keygen>
<param>
<source>
<track>
<wbr>
现存所有的无内容元素就是以上这些了。
<br></br>
这样的写法是不合法的 HTML 写法,因为它暗示 br
可以包含内容(但 <br>你好!</br>
是完全没有意义的)。而 <br>
和 <br />
这两种写法都很常见。
尽管我们都知道 XHTML 强制你必须写成 <br />
,但 HTML 里却没有明文规定。
追溯历史
为了完全地了解无内容元素,我们有必要了解一下它的历史。
HTML、XML 和 XHTML 都是基于 SGML 的,SGML 的全称是“标准通用标记语言”,起草于1986年。
HTML 和 XML 都派生自 SGML,其中 XML 是 SGML 的约束性子集,而 XHTML 是基于 XML 的。
XHTML 基本上和 HTML 一样,但是是基于 XML 的。
知道这层关系后,接下来进入本文最有意思的部分。
SGML 有一个特性叫做“无尾标签(NET,Null End Tag)”。当标签内只有简单的文字的时候,使用无尾标签就可以无须再闭合这个标签了。比如你可以把 <quote>Quoted text</quote>
写成 <quote/Quoted text/
。(你没有看错,这个标签中不含 >
。)
那么,不包含任何内容的标签就可以写成 <quote//
了,其中 quote 是标签名,第一个 /
用于启用无尾标签,第二个 /
表示无尾标签结束。
如果按照这个逻辑,<br//
中的前半部分 <br/
会被解析为 <br>
,那么 <br/>
岂不是要被解析为 <br>>
了吗?如果你和我想得一样,你肯定也会觉得这种语法很蠢。
不幸的是 HTML4 规范的制定者们不这么认为,并且把它写进规范里了。不过显然当时的浏览器厂商对这种语法也不以为然,支持的程度不大。(在这一点上,说不定浏览器厂商们做了一件好事。)
XML (也适用于 XHTML)规范的制定者意识到这种语法不怎么好,就直接没有包含无尾标签这种特性,
同时为无内容标签提供了一种比较好理解的语法。这种语法的名字叫做“无元素标签”,它看起来是这样的:<br />
。这种语法看起来非常自然,因此当时的大多数开发者都认为这才是正确的写法。
幸运地是 HTML 一直在改进,W3C 的成员一直在从他们过去作出的错误中学习经验教训。因此 HTML5 相比之前的版本才有这么大的进步。
在介绍 HTML5 的新语法时, W3C 说:
HTML5 的语法完全兼容 HTML4 和 XHTML1,但是不兼容 SGML 中那些晦涩的 HTML4 特性。比如无尾标签(
<em/content/
)。
HTML5 好样的!
(我觉得他们应该保留“短标签”特性,比如 <strong>不错喲</>
,我觉得这个特性很酷。不过,至少现在的 HTML 已经不再是那么杂乱无章了。)
合法性
好吧,我们回到文章开头关于合法性的问题,目前的 HTML5 规范中关于非内容标签的解释是这样的:
此类标签应由下列部分组成,顺序须与下表保持一致:
- 一个 “<” 字符。
- 标签名。
- 此项可选,一个或多个属性,每一个属性的前面必须有一个或多个空格。
- 此项可选,一个或多个空格。
- 此项可选,一个 “/” 字符,此项只能在无内容元素中出现。
- 一个 “>” 字符。
倒数第二部分的 “/” 字符是可选的,而且没有任何实际含义。所以 <br>
和 <br />
其实没有实质区别。
正确性
喜欢 XML 和 XHTML 的开发者可能会说,“对呀,虽然 /
是可选的,但是 <br />
的写法‘更正确’一些。”
我必须告诉你你错了。事实上,有观点认为无内容标签里的 /
其实是一个被容忍的语法错误。这种容忍是基于兼容性考虑的,它使得所有浏览器和解析器都把 <br>
和 <br />
同等对待。
关于这一点,Google 代码风格指南 也明确规定了不要关闭无内容标签。
缺点
当然,不关闭无内容标签也有弊端,不过我认为这掩盖不了它的优点:使你的代码干净简洁。
第一个缺点就是开发者必须知道哪些标签的无内容标签。假设你不知道 <img>
是不是无内容标签,那么当你找不到它的闭合标签时,你就会疑惑到底应不应该关闭这个标签。不过无内容标签总共也只有那么几个,而且一般一眼就能看出来某个标签是不是无内容标签。
第二个缺点是编辑器可能对没有闭合的无内容标签处理不好。编辑器的开发者们必须了解无内容标签,提供恰当的语法高亮和代码补全。当你在编辑器里写了一个 <input>
,编辑器必须要知道它后面永远不会接一个 </input>
。
但是这些功能实现起来很简单,我所知道的编辑器对这方面支持得都还挺好,所以这算不上一个真正的缺点。