前言
直接在p元素中嵌套div标签的时候,p标签会被div分成上下两个p元素
p{
height: 50px;
width: 300px;
background-color:lightblue;
}
div{
height: 100px;
width: 100px;
background-color:red;
}
<p>p1
<div>div1</div>
</p>
原因
有很多博文直接给出结论:
- 行内元素不能嵌套块级元素
- 块级元素可以包含行内元素或某些块元素,但是行内元素不能包含块元素,它只能包含其他的行内元素。
- 有几个特殊的块级元素只能包含行内元素,不能再包含块级元素:h1~h6、p、dt
- 块级元素不能放在标签 p 里面
- li 标签可以包含标签,因为 li 和 div 标签都是装载内容的容器
原因也确实是如此,但是还是没有告诉我们为什么,最后我找到原因所在:W3C HTML5标准中的元素分类与内容模型(Content Model)
重点的内容
前言
在HTML5中,标准制定者重新定义了HTML元素的分类,并根据这一新的分类定义了元素的内容模型(Content Model) -- 对于一个元素而言,哪些子元素是合法的,而哪些子元素是非法的。
HTML5中,元素主要分为7类:
- Metadata
- Flow
- Sectioning
- Heading
- Phrasing
- Embedded
-
Interactive
这些分类集合互相之间也存在一定的交集(一个元素可以同时属于多个分类),其交集关系呈现为:
demo2.jpg需要注意的是,HTML5中的这种元素分类与inline、block没有任何关系,任何元素都可以在CSS中被定义为display:inline或者display:block。另外,除了这7大分类,还存在一些较小的分类,如Palpable、Script-Supporting等。
Metadata
顾名思义,Metadata元素意指那些定义文档元数据信息的元素 — 其作用包括:影响文档中其它节点的展现与行为、定义文档与其它外部资源之间的关系等。以下元素属于Metadata:base, link, meta, noscript, script, style, template, title。
Flow
所有可以放在body标签内,构成文档内容的元素均属于Flow元素。因此,除了base, link, meta, style, title等只能放在head标签内的元素外,剩下的所有元素均属于Flow元素。
Sectioning
Sectioning意指定义页面结构的元素,具体包含以下四个:article, aside, nav, section。
Heading
所有标题元素属于Heading,也即以下6个元素:h1, h2, h3, h4, h5, h6。
Phrasing
所有可以放在p标签内,构成段落内容的元素均属于Phrasing元素。因此,所有Phrasing元素均属于Flow元素。在HTML5标准文档中,关于Phrasing元素的原始定义为:
Phrasing content is the text of the document, as well as elements that mark up that text at the intra-paragraph level. Runs of phrasing content form paragraphs.
对于这一定义,个人认为不应当使用“text”这一容易引起误解的词,事实上,一个元素即使不是文本,只要能包含在p标签中成为段落内容的一部分,就可以称之为Phrasing元素。比如:audio、video、img、select、input等元素(经测试,这些元素都可以放置在p标签中)。一个不太精确的类比是:HTML5中的Phrasing元素大致就是HTML4中所定义的inline元素。
Phrasing元素内部一般只能包含别的Phrasing元素。
Embedded
所有用于在网页中嵌入外部资源的元素均属于Embedded元素,具体包含以下9个:audio, video, img, canvas, svg, iframe, embed, object, math。
Interactive
所有与用户交互有关的元素均属于Interactive元素,包括a, input, textarea, select等。
内容模型(Content Model)
根据以上元素分类,HTML5标准文档定义了任何元素的内容模型 — 对于该元素而言,何种子元素才是合法的。
比如,对于p元素而言,其内容模型为Phrasing, 这意味着p元素只接受Phrasing元素为子元素,而对于像div这样的非Phrasing元素则并不接受。类似的,li元素的内容模型为Flow,因此任何可以放置在body中的元素都可以作为li元素的子元素。
值得注意的是,HTML5标准文档在定义元素的内容模型时,会使用一类特殊的分类:透明内容模型(transparent) — 对于内容模型为透明(transparent)的元素而言,其子元素的合法性由其父元素所决定;如果其父元素的内容模型仍为透明,则查看其祖父元素的情况,并依此类推;如果向上推演至body标签仍未找到任何内容模型非透明的父级元素,则该透明元素内部可包含任何Flow元素。
典型的具有透明内容模型的元素为a元素。因此,当a出现在p标签中时,a不能接受div作为子元素;而当a出现在div标签中时,a可以接受div作为子元素。