HTML 标签嵌套规则

HTML4/XHTML 嵌套规则

Inline Level 和 Block Level

在 HTML4/XHTML DTD 中,将元素的分为 inline level (行内级) 和 block level (块级) 两类。

  • inline level
1
span、a、dfn、abbr、cite、img、label、q、u、em、i、strong、b、big、small、sub、sup、表单类;计算机输出类(tt、kbd、code、var、samp)
  • block level
1
div、h1-h6、hr、ul、ol、dl、li、fieldset、address、from、table、html5 中新增的结构化语义标签、pre、blockquote、dir、menu

注:HTML 中的 inline level、block level 与 CSS 中的 inline、block 意义不一样,HTML 强调的是语义和结构,而 CSS 强调的是样式。要不然无法解释:

1
span {display: block;}
1
<span><div></div></span>

嵌套规则

  • 块元素可以包含内联元素或某些块元素,但内联元素却不能包含块元素,它只能包含其它的内联元素(另,a 不能在嵌套 a):
1
2
3
4
5
6
<!-- 对 -->
<div><h1></h1><p></p></div>
<!-- 对 -->
<a href=”#”><span></span></a>
<!-- 错 -->
<span><div></div></span>
  • 有几个特殊的块级元素只能包含内嵌元素,不能再包含块级元素,这几个特殊的标签是:h1、h2、h3、h4、h5、h6、p、dt
1
2
3
4
<!-- 错 -->
<p><ol><li></li></ol></p>
<!-- 错 -->
<p><div></div></p>

HTML5 嵌套规则

HTML5 规范中,已经不按 inline level 和 block level 来区分元素类型了,元素按 Categories 分类,元素的 Content Model 规定了合法的元素内容类型。

Categories

  • Metadata 元数据信息元素
1
base, link, meta, noscript, script, style, template, title
  • Flow 流式元素

所有可以放在 body 标签内,构成文档内容的元素均属于 Flow 元素,即,除了 base, link, meta, style, title 等只能放在 head 标签内的元素外,剩下的均属 Flow 元素。

  • Sectioning 结构元素
1
article, aside, nav, section
  • Heading 标题元素
1
h1, h2, h3, h4, h5, h6
  • Phrasing 短语元素

所有可以放在 p 标签内,构成段落内容的元素均属于 Phrasing 元素。HTML5 中的 Phrasing 元素大致就是 HTML4 中所定义的 inline level 元素。另外,所有 Phrasing 元素均属于 Flow 元素。

  • Embedded 嵌入资源元素
1
audio, video, img, canvas, svg, iframe, embed, object, math
  • Interactive 交互元素
1
a, audio, video, button, details, embed, iframe, img, input, label, object, select, textarea

Content Model

各元素都有自己的 Content Model,比如 a 元素的 Content Model 为 transparent,这类元素本身内部可以有任何类型的内容,是否合法要看其父元素的 Content Model 和其内容的 Categories,还有 p 元素,其内容模型为 Phrasing, 这意味着 p 元素只接受 Phrasing 元素为子元素(p 自身 Categories 类型为 Flow content,因而 p 不能嵌套 p)。

下面例子中的嵌套都是不合法的。

1
2
3
4
<!-- p>ins>a>div 错误 -->
<p><ins><a href=""><div></div></a></ins></p>
<!-- ul>li>h4>a>div 错误 -->
<ul><li><h4><a href=""><div></div></a></h4></li></ul>

p 元素的 content model 是 phrasing content,ins 本身属于 phrasing content 故可以嵌套;ins 元素的 content model 是 transparent,故在此时里面是否能有 a 需检查 p>a 的合法性;a 元素也属于 phrasing content,故 p>ins>a 合法;a 元素的 content model 也是 transparent,故此时里面包含 div 的合法性向上传递,检查 ins>div 又向上传递,变成检查 p>div。所以,div 不属于 phrasing content,这个嵌套是不合法。