从a标签为什么不能包含div标签-了解HTML5元素分类与内容模型

我们知道按新的 HTML 规范,已经不按 inline 和 block 来区分元素类型了。所以我们在a标签里面使用div标签时候会发现a标签并不能通过改变css盒子模型的方式将div元素包含。

元素分类

HTML5中,元素主要分为7类:

Metadata

Flow

Sectioning

Heading

Phrasing

Embedded

Interactive

这些分类集合互相之间也存在一定的交集(一个元素可以同时属于多个分类),其交集关系呈现为:

需要注意的是,HTML5中的这种元素分类与inline、block没有任何关系,任何元素都可以在CSS中被定义为display:inline或者display:block。另外,除了这7大分类,还存在一些较小的分类,如Script-Supporting元素等。

Metadata(元数据元素)

顾名思义,Metadata元素意指那些定义文档元数据信息的元素 — 其作用包括:影响文档中其它节点的展现与行为、定义文档与其它外部资源之间的关系等。以下元素属于Metadata:

base, link, meta, noscript, script, style, template, title

Flow(流式元素)

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

a, abbr, address, area, article, aside, audio, b, bdi, bdo, blockquote, br, button, canvas, cite, code, command, datalist, del, details, dfn, div, dl,em, embed, fieldset, figure, footer, form, h1, h2, h3, h4, h5, h6, header, hgroup, hr, i, iframe, img, input, ins, kbd, keygen, label, map, mark, math, menu, meter,nav, noscript, object, ol, output, p, pre, progress, q, ruby, s, samp, script, section, select, small, span, strong, style(如果该元素设置了scoped属性), sub, sup, svg, table,textarea, time, u, ul, var, video, wbr, text

Sectioning(章节元素)

Sectioning意指定义页面结构的元素,具体包含以下四个:

article, aside, nav, section

Heading(标题元素)

所有标题元素属于Heading,也即以下6个元素:

h1, h2, h3, h4, h5, h6

Phrasing(段落元素)

所有可以放在p标签内,构成段落内容的元素均属于Phrasing元素。因此,所有Phrasing元素均属于Flow元素。

对于这一定义,个人认为不应当使用“text”这一容易引起误解的词,事实上,一个元素即使不是文本,只要能包含在p标签中成为段落内容的一部分,就可以称之为Phrasing元素。

a(如果其只包含段落式元素), abbr, area, audio, b, bdi, bdo, br, button, canvas, cite, code, command, datalist, del(如果其只包含段落式元素), dfn, em, embed, i,iframe, img, input, ins(如果其只包含段落式元素), kbd, keygen, label, map(如果其只包含段落式元素), mark, math, meter, noscript, object, output, progress, q, ruby, s, samp, script,select, small, span, strong, sub, sup, svg, textarea, time, u, var, video, wbr, text

一个不太精确的类比是:HTML5中的Phrasing元素大致就是HTML4中所定义的inline元素。

Phrasing元素内部一般只能包含别的Phrasing元素。

Embedded(嵌入元素)

所有用于在网页中嵌入外部资源的元素均属于Embedded元素,具体包含以下9个:

audio, video, img, canvas, svg, iframe, embed, object, math

Interactive(交互元素)

所有与用户交互有关的元素均属于Interactive元素。

a, audio(如果设置了controls属性), button, details, embed, iframe, img(如果设置了usemap属性), input(如果type属性不为hidden状态), keygen, label, menu(如果type属性为toolbar状态),object(如果设置了usemap属性), select, textarea, video(如果设置了controls属性)

Palpable

所有应当拥有子元素的元素称之为Palpable元素。比如,br元素因不需要子元素,因此也就不属于Palpable。

Script-supporting

自身不做任何页面展现,但与页面脚本相关的元素,具体包括2个:

script, template

内容模型(Content Model)

根据以上元素分类,HTML5标准文档定义了任何元素的内容模型 — 对于该元素而言,何种子元素才是合法的。

比如,对于p元素而言,其内容模型为Phrasing, 这意味着p元素只接受Phrasing元素为子元素,而对于像div这样的非Phrasing元素则并不接受。类似的,li元素的内容模型为Flow,因此任何可以放置在body中的元素都可以作为li元素的子元素。

值得注意的是,HTML5标准文档在定义元素的内容模型时,会使用一类特殊的分类:透明内容模型(transparent) — 对于内容模型为透明(transparent)的元素而言,其子元素的合法性由其父元素所决定;如果其父元素的内容模型仍为透明,则查看其祖父元素的情况,并依此类推;如果向上推演至body标签仍未找到任何内容模型非透明的父级元素,则该透明元素内部可包含任何Flow元素。

正确嵌套标签

元素的嵌套规则和页面头部申明的DTD有着千丝万缕的关系,通过了解HTML5的元素分类与内容模型,我们能更清楚的指导我们元素的嵌套关系。虽然大部分浏览器都有容错机制,写出来的代码在浏览器下表现没有什么异样,但作为一个专业开发人员,我们必须对待自己的代码应该一丝不苟,即使HTML5的胸襟很宽广,但我们更应该去遵从W3C,因为只有标准健壮的代码,才会有更好的扩展与兼容。

总结

因此a标签内是否合可以包含div标签要看其父元素的 content model 和其内容的 categories。比如我们要看 p > ins > a > div 是否合法,过程是这样的: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,所以这个嵌套是不合法的。

猜你喜欢

转载自www.cnblogs.com/homehtml/p/11800126.html