你有没有想过,如果把 br
或 input
标签闭合起来,像 <br />
会不会好点?或者在HTML5里面写成 <br>
会不会更好一点? 或者为什么把SCRIPT写成这样是不正确的 <script src="script.js" />
? 好吧,我想过这些, 并且在寻找答案的时侯,我发现很多趣的东西 (比如某种奇怪的原因,你会觉得这东西很有意思).
如果你对其中的原委不感兴趣,就直接跳到节«有效性»获取你的答案。
VOID 元素
空(void)元素是一种特殊的元素,绝对不能有内容。这跟其他元素是一个很大的区别;其他可以为空,但也可以包含其他元素或文本(例如<div>) 。
最知名的空元素是:
<br>
<hr>
<img>
<input>
<link>
<meta>
鲜为人知的是:
<area>
<base>
<col>
<command>
<embed>
<keygen>
<param>
<source>
<track>
<wbr>
就是这样。这些都是现有的空元素。
它不能,也从来没有过,将有效的HTML写成 <br></br>
, 因为这样会导致 br
元素拥有内容 (<br>Hello!</br>
这样的写法完全没有意义). 然而,这是很常见的写法 <br>
和 <br />
.
虽然大多数人都知道,在XHTML中,它是强制性写成 <br />
但对HTML的规则没有要求。
历史
了解空(void)元素的历史,是有必要的。
HTML, XML 和 X(HT)ML 都是基于 SGML 的, HTML,XML和X ( HT)的ML都是基于SGML ,标准通用标记语言成型于1986年。HTML和XML直接从SGML继承。 XML是SGML的一个更严格的子集,这就是XHTML的基础。
XHTML写HTML基本相同 ,但基于XML。
到目前为止?好,然后到了有趣的部分:
SGML 有个功能叫 NET (Null End Tag). 这是一个简短的表示法,以避免关闭标签,当你的内容是简单的文本。使用NET写法,你可以用 <quote/Quoted text/
inste代替的 <quote/Quoted text/
instead of <quote>Quoted text</quote>
.
另外说明,不包含任何文本元素,可以写成所谓的SHORTTAG NETENABL IMMEDNET <quote//
它跟这样的写法是等价的 <quote></quote>
.
那么,按照这种逻辑,如果一个空元素没有结束标签, <br/
将被解释为 <br>
, 和 <br/>
然后会被解释成 <br>>
这显然是不正确的语法。你可能像我一样,在想«这真是疯了! » 。不幸的是, HTML4规范的作者不这样认为,这就是为什么这是规范的一部分的原因。显然,浏览器厂商在当时并没有采用,这导致非常差的浏览器支持(其实在这种情况下,这可以说并不是一件坏事) 。
XML (以及XHTML)不认可这种疯狂的语法,并没有包括NET或SHORTTAG NETENABL IMMEDNET 的功能 ,而是提供一个健全的语法无效要素,即空元素看起来像这样: < BR / > 。这看很自然这也就是为什么大多数开发人员认为这是正确的书写方式。
幸运的是推动HTML发展的人们在万维网联盟(起草和整个网络设置标准的人们)也是从他们过去的错误中学习。这也是为什么HTML5变得友好得匀的原因。
在引进新的HTML5语法中, W3C的提到:
HTML 5中定义的HTML语法与HTML 4和在Web上发布的XHTML 1文件兼容,但不使用HTML 4是一些比较晦涩的SGML功能,如NET语法(如<em/content/)。
做得对 HTML5! (OurJS注* W3C标准委员会也会犯错,但目前关于HTML还没有错的特别离谱,这在后续的标准里都得到了纠正)
我想他们应该已经保留一些比较酷的标准,像 (<strong>Hell yea</>
) 但是他们没有,至少HTML变得不那么混乱了)
有效性
再回到有效性的问题validity, 目前的 HTML5 specification for void elements (HTML5关吉void元素的规范)是这样:
开始标记由以下几部分组成,严格按照下列顺序:
- 一个 "<" 字符.
- 元素的标记名称.
- 可选的,一个或多个属性,其中每一个的前面必须有一个或多个空格字符。
- 可选的,一个或多个空格字符。
- 可选的,一个“/”字符,它可以存在且仅当元素是一个空元素时。
- 一个 ">" 字符
这意味着“/“”字符在HTML5中是可选的,它不添加任何意义。<br>和<br />之间完全没有差别。
正确性
那么,对于那些你们真正沉迷于X( HT ) ML的人来说,你可能会想:是的,它是可选的,但是<br />
i仍然“更正确” ,但我要告诉你:这不是。事实上,人们可能会说,这种在void元素上添加 / 标签是语法错误。但可能大多考虑到了兼容性的原因,每一个浏览器都将<br>和<br />做相同处理。
谷歌的编程风格指南(Google's styleguide)对这一议题也很清楚的指出,你不应该关闭空白标签。
理论上的缺陷
当然,非闭合标签有其缺点,但我认为他们没有像<META>这样干净简洁不闭合标签的优势。
不关闭标签的第一个缺点是用户必须有void标签的知识。例如,你不知道什么是<img>元素,你可能会感到困惑,因为你不能找到任何结束标记它。但不关闭标签很短,通常这是非闭合标签相当明显的标志。
第二个缺点是,它使编辑器变得更为复杂。他们需要有空白标记的完整列表,以提供适当的高亮和自动完成代码。如果您在编辑器中编写<INPUT> ,它必须知道,永远不会有一个< /input>自动填补。
但它是非常容易实现的,所以它不是一个真正的缺点。
我对VOID标签的一点建议
我认为,可以给一些标签的添加内容,而不是定义附加属性而产生非闭合标签。让我们举例来说<img>标签。它有一个强制性的alt属性,理由也很充分:无法看到图像的那些人(或者是因为他们的设备不支持)至少应该知道这图片是描述什么的,他们可以看到有一(如果您要添加一个img标记仅用于设计目的,那么你没有做错什么)。所以我的疑问是:为什么不在图像标记里添加替代标记的内容?这似乎相当明显,比如我写成<img src="doge.png">Image of doge</img>
. 。这同样适用于<meta>标记!为什么不直接使用,实际的元素内容?<input>Value content</input>
替换掉<TEXTAREA>之类的。
所以,应该只存在很和的几旧空标签,但显然W3C已经采取向后兼容性,这使得这种改变困难得多。
最后的思考: <SCRIPT>标签
script标签,确实一直困扰着我,因为它是这样一个简单的指令,相比一个冗长的标签。这似乎是错误的写法 <script src="my-script.js"></script>
因为这个脚本标记的内容有逻辑关联到我的script.js (HTML规范不允许同时添加,内容和src属性) 。
但问题是, <SCRIPT>不是一个空白标签,因为你可以内联的JavaScript在网页上,并不是“可选的空白标签” 。
<link>标记的解决方案本来很完美,因为它采用其他接口(style),并提供一切必要的,包括外部文件的属性。当然,正如上文提到,不能用的原因是向后兼容,因为所有旧的浏览器不支持这种语法。
嗯,<link>标签和<style>标签分开,但<script>标签却一体的,这个是HTML中一个不统一的地方。
另外还有<input type="button" value="内容" > 这个写成: <input type="button">内容</input>更直观合理才对。
总之产生这些不全常规或者不合理的原因,还是兼容性的问题。
<input type="button">
已经用得比较少了,现在都在用
<button>内容</button>