咱们知道按新的 HTML 规范,已经不按 inline 和 block 来区分元素类型了。因此咱们在a标签里面使用div标签时候会发现a标签并不能经过改变css盒子模型的方式将div元素包含。css
HTML5中,元素主要分为7类:canvas
Metadata浏览器
Flowruby
Sectioningide
Headingsvg
Phrasingspa
Embeddedcode
Interactiveorm
这些分类集合互相之间也存在必定的交集(一个元素能够同时属于多个分类),其交集关系呈现为:cdn
须要注意的是,HTML5中的这种元素分类与inline、block没有任何关系,任何元素均可以在CSS中被定义为display:inline或者display:block。另外,除了这7大分类,还存在一些较小的分类,如Script-Supporting元素等。
顾名思义,Metadata元素意指那些定义文档元数据信息的元素 — 其做用包括:影响文档中其它节点的展示与行为、定义文档与其它外部资源之间的关系等。如下元素属于Metadata:
base, link, meta, noscript, script, style, template, title
全部能够放在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意指定义页面结构的元素,具体包含如下四个:
article, aside, nav, section
全部标题元素属于Heading,也即如下6个元素:
h1, h2, h3, h4, h5, h6
全部能够放在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元素,具体包含如下9个:
audio, video, img, canvas, svg, iframe, embed, object, math
全部与用户交互有关的元素均属于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元素。好比,br元素因不须要子元素,所以也就不属于Palpable。
自身不作任何页面展示,但与页面脚本相关的元素,具体包括2个:
script, template
根据以上元素分类,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,因此这个嵌套是不合法的。