HTML5与HTML4的元素嵌套规则

HTML4的元素嵌套规则

在我们的印象中会有这样的嵌套规则:


http://caibaojian.com

内联元素不能嵌套块元素
<p>元素和<h1~6>元素不能嵌套块元素

详见 Jukka Korpela 的 Allowed nesting of elements in HTML 4 Strict (and XHTML 1.0 Strict)
那么到底什么是块元素,什么是内联元素?

以下是W3C CSS2.1规范中对块元素和内联元素的定义:
**Block-level elements
** are those elements of the source document that are formatted visually as blocks (e.g., paragraphs). The following values of the ‘display’ property make an element block-level: ‘block’, ‘list-item’, and ‘table’.

**Inline-level elements
** are those elements of the source document that do not form new blocks of content; the content is distributed in lines (e.g., emphasized pieces of text within a paragraph, inline images, etc.). The following values of the ‘display’ property make an element inline-level: ‘inline’, ‘inline-table’, and ‘inline-block’. Inline-level elements generate inline-level boxes
, which are boxes that participate in an inline formatting context.

我们可以这样理解:块元素一般都从新行开始,内联元素在一行内显示,我们也可以通过CSS属性display的’inline’ 或 ‘ block’ 来改变元素为内联元素或块元素,当然这是CSS中对元素的分类,显然用 ‘display’ 的属性值来对html元素进行分类是不严谨的。

HTML5的元素嵌套规则

让我们先了解下W3C在最新的HTML5规范中对元素的分类方式:

w3c html5 content

如上图,元素的分类不再是块元素或内联元素这样来分类(其实从来就没有这样分),而是按照如下分类来分:Flow(流式元素)、Heading(标题元素)、Sectioning(章节元素)、Phrasing(段落元素)、Embedded(嵌入元素)、Interactive(交互元素)、Metadata(元数据元素)。


Flow(流式元素)
在应用程序和文档的主体部分中使用的大部分元素都被分类为流式元素

a, abbr, address, area(如果它是map元素的后 裔), 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


Heading(标题元素)

标题式元素定义一个区块/章节(section)(无论是明确的使用章节式内容的元素标记,或者标题式内容自身所隐含的)的标题。
h1, h2, h3, h4, h5, h6, hgroup


Sectioning(章节元素)

章节式元素是用于定义标题及页脚范围的元素。
article, aside, nav, section


Phrasing(段落元素)

段落式元素是文档中的文本、标记段落级文本的元素。
a(如果其只包含段落式元素), abbr, area(如果它是map元素的后 裔), 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


Embedded(嵌入元素)

嵌入式元素是引用或插入到文档中其他资源的元素。
audio, canvas, embed, iframe, img, math, object, svg, video


Interactive(交互元素)

交互式元素是专门用于与用户交互的元素。
a, audio(如果设置了controls属 性), button, details, embed, iframe, img(如果设置了usemap属性), input(如果type属性不为 hidden状态), keygen, label, menu(如果type属性为toolbar状态),object(如果设置了usemap属 性), select, textarea, video(如果设置了controls属性)


Metadata(元数据元素)

元数据元素是可以被用于说明其他内容的表现或行为,或者在当前文档和其他文档之间建立联系的元素
base,command,link,meta,noscript,script,style,title


各分类会有交叉或重叠的现象,这说明在html5中,元素可能属于上述所有分类中的一个或多个。

举个栗子1:<h1>~<h6>元素:
  • Categories:

  • Flow content.

  • Heading content.

  • Palpable content.

  • Contexts in which this element can be used:As a child of an hgroup element.

  • Where flow content is expected.

  • Content model:

  • Phrasing content.

其中的「Categories」说明该元素的类别,「Contexts in which this element can be used」说明该元素能在何种场景下被使用,也就是它的父元素是什么,「Content model」说明该元素可以包含的内容是什么,由于页面中的元素是层层嵌套的,一个元素有可能既是父元素同时也是子元素的角色,所以下面我们以「Content model」也就是可包含的子元素做讨论。
那么对于h1~h6元素:
它们同时属于Flow contentHeading content 和** Palpable content**三个分类;
它们的父元素可以是<hgroup>,同时那些子元素是流式元素的元素也可以作为h1-h6元素的父元素;
它们允许的子元素是段落式元素。

举个栗子2:<div>元素
  • Categories:

  • Flow content.

  • Palpable content.

  • Contexts in which this element can be used:

  • Where phrasing content is expected.

  • Content model:

  • Flow content.

对于<div>元素:
同时属于Flow content 、** Palpable content**分类
父元素必须是那些子元素为段落式元素的元素
允许的子元素是流式元素

<div>元素允许的子元素是流式元素,流式元素基本涵括了页面中的大部分元素,所以我们在用<div>时可以不用担心嵌套错误的问题。
但对于<h1>~<h6>元素,它们允许的子元素为段落式元素,而段落式元素并不包含诸 如<div>、<p>、<ul>、<ol>之类的元素,这就说明按照html5的规范,是不允许在标题元 素内部嵌入<div>、<p>、<ul>、<ol>之类的元素。

举个栗子3:<a>元素
  • Categories:

  • Flow content.

  • Phrasing content.

  • Interactive content.

  • Palpable content.

  • Contexts in which this element can be used:

  • Where phrasing content is expected.

  • Content model:

  • Transparent, but there must be no interactive content descendant.

对于<a>元素:
同时属于Flow content 、** Phrasing contentInteractive contentPalpable content**分类
父元素必须是那些子元素为段落式元素的元素
允许的子元素是以它的父元素允许的子元素为准,但不能包含交互式元素

这样看<a>元素还是挺有意思的,允许的子元素要看它的父元素所能包含的子元素。


再来看下面的代码

<ul>   
<li><h4><a href=""><div></div></a></h4></li>
</ul>

这时<a>的父元素为<h4>,对于<h1>~<h6>的标题元素上面已经提过,允许的子元素是 段落式元素,那么此时对于<a>允许的子元素即为段落式元素,而段落式元素中是不包含<div>元素的,所以这样的嵌套方法是错误的!

让我们来把代码做一下修改:

<ul>   
<li><div><a href=""><div></div></a></div></li>
</ul>

这时<a>的父元素为<div>,而<div>元素允许的子元素是流式元素,流式元素中包含<div>元素,所以这样的情形下在<a>里面嵌套<div>就是正确的做法!


嵌套错误可能引起的问题

上面讲了HTML5对元素新的分类方式和以<h1>~<h6>、<div>、<a>元素举例讲述 了各自的嵌套规则,但不按照标准去嵌套也不会有大的错误问题,这就给我们带来了一个思考:嵌套错误到底会不会有问题?

举个栗子1:开始与结束标签嵌套错误
<div><h2>内容</div></h2>

测试结果:

element11

举个栗子2:<p>元素嵌套<div>元素
<p><div>内容</div></p>

测试结果:

element12

举个栗子3:列表元素<li>兄弟元素为<div>
<ul><li>内容</li><div>内容</div></ul>

测试结果:

element13

举个栗子4:<h2>元素嵌套<div>元素
<h2><div>内容</div></h2>

测试结果:

element14

举个栗子5:<a>元素嵌套<a>元素
<a href=""><a href="">内容</a></a>

测试结果:

element15

通过上述栗子,我们总结如下:

  • 元素开始与结束标签嵌套错误,页面可以在大部分浏览器被正常解析,IE9会出现解析错误;

  • <p>元素内嵌入<div>等元素造成所有浏览器的解析错误;

  • <h1>~<h6>元素内嵌入<div>等元素所有浏览器可以解析正常;

  • <a>元素内嵌入<a>元素会导致所有浏览器的解析错误;

  • 在列表元素<li><dt><dd>等插入非列表兄弟元素会导致IE6IE7的解析错误;

    其实,这里说解析错误并不是很合理,应该是说浏览器解析出来的结果和我们期望的结果不一致,但任何的嵌套错误都不会导致页面呈现有很大的出错。
    我们知道JS代码如果写的有语法错误,浏览器的JS解释器就会拒绝执行并且报错,而浏览器在遇到不符合语法规定的HTML代码时则会千方百计将其呈现出来。

严格嵌套约束、语义嵌套约束

通过上面的示例我们发现在<p>元素里嵌套<div>元素或者<a>元素里<a>元素会导致所有的浏览器都解析错误,这其实是W3C规范的严格嵌套约束,严格嵌套约束要求必须去遵守,不然就会导致所有浏览器的解析错误。

严格嵌套约束规则:
a元素里不可以嵌套交互式元素(<a><button><select>等)
<p>里面不可以嵌套<div>、<h1>~<h6>、<p>、<ul>/<ol> /<li>、<dl>/<dt>/<dd>、<form>

语义嵌套约束:
 每个元素基本都有自己的嵌套规则(即父元素可以是什么,子元素可以是什么),除了严格嵌套约束之外的一些规则就是语义嵌套约束,对于语义嵌套约束,如果不遵守,页面可能正常,但也可能解析错误,这和下面要讲的容错机制有关。

浏览器的容错机制

并不是每位同学在写完页面后去做合法性检查,因此浏览器厂商不得不让它们的浏览器以尽可能宽松的方式去处理网页,每个浏览器内核中都有相当一部分代码专门用来处理那些含糊不清的html标记及嵌套,并且会去猜测前端们到底想如何呈现网页,这是浏览器的容错机制
 这其实在告诉我们,我们写出来的HTML代码不符合W3C规范可能最终呈现出来没有异样,但那其实是浏览器的一种容错机制,我们没有理由让自己以一个随性的态度去coding,对待自己的代码应该一丝不苟,即使HTML5的胸襟很宽广。

注:原文来自 http://caibaojian.com
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,703评论 1 92
  • 一:在制作一个Web应用或Web站点的过程中,你是如何考虑他的UI、安全性、高性能、SEO、可维护性以及技术因素的...
    Arno_z阅读 1,126评论 0 1
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,490评论 18 139
  • <a name='html'>HTML</a> Doctype作用?标准模式与兼容模式各有什么区别? (1)、<...
    clark124阅读 3,451评论 1 19
  • 前言自从开始写故事之后很多人跟我分享他们的故事有喜有乐,无论哪种声音我都一一倾听最近的一个故事让我有不得不写的冲动...
    丸子大人阅读 758评论 0 0