HTML标签嵌套规则

2017-1-31 13:11| 作者: 蚂蚁小编| 查看: 11920| 评论: 0|来自: 蚂蚁部落

本文介绍一下HTML的嵌套规则,先看一段代码:

[HTML] 纯文本查看 复制代码
<ul>
  <li>
    <h4><a href=""><div></div></a></h4>
  </li>
</ul>

上面的代码来自于FACEBOOK,大家对于上面HTML标签的相互嵌套关系是否感觉有所不妥。

下面先对HTML标签的嵌套规则进行一下介绍,然后再对上面的代码进行一下分析。

一.HTML4/XHTML的嵌套规则:

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

1.png

规则如下:

(1).内联元素不能嵌套块元素。

(2).<p>元素和<h1~6>元素不能嵌套块元素。

关于块级元素和内联元素:

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

如果按照上述规则来讲,FACEBOOK做法就是一种错误的,因为它在内联元素<a>元素中嵌套了块元素元素<div>,但上述规则是基于HTML4/xHTML1的strict模式,而FACEBOOK现在已经统一使用了html5的doctype,那么这个规则到底还是是否适用呢。

二.HTML5的元素嵌套规则:

W3C在最新的HTML5规范中对元素的分类方式:

2.png

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

Flow(流式元素):

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


[HTML] 纯文本查看 复制代码
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)(无论是明确的使用章节式内容的元素标记,或者标题式内容自身所隐含的)的标题。

[HTML] 纯文本查看 复制代码
h1, h2, h3, h4, h5, h6, hgroup

Sectioning(章节元素):

章节式元素是用于定义标题及页脚范围的元素。

[HTML] 纯文本查看 复制代码
article, aside, nav, section

Phrasing(段落元素):

段落式元素是文档中的文本、标记段落级文本的元素。

[HTML] 纯文本查看 复制代码
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(嵌入元素):

嵌入式元素是引用或插入到文档中其他资源的元素。

[HTML] 纯文本查看 复制代码
audio, canvas, embed, iframe, img, math, object, svg, video

Interactive(交互元素):

交互式元素是专门用于与用户交互的元素。

[HTML] 纯文本查看 复制代码
a, audio(如果设置了controls属性), button, details, embed, iframe, img(如果设置了usemap属性), 
input(如果type属性不为hidden状态), keygen, label, menu(如果type属性为toolbar状态),
object(如果设置了usemap属性), select, textarea, video(如果设置了controls属性)

Metadata(元数据元素):

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

[HTML] 纯文本查看 复制代码
base,command,link,meta,noscript,script,style,title

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

代码实例一:

<h1>~<h6>元素:

所属分类:

(1).Flow content。

(2).Heading content。

(3).Palpable content.

特别说明:

元素还可以有其他分类类型,具体可以参阅https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories。不过嵌套规则,使用上面几个分类足以阐述清楚;关于Palpable content是何种类型上面有介绍。

使用场景:

(1).作为hgroup元素的子元素。

(2).作为可以容纳flow content类型元素的子元素。

可以包含的元素:

(1).可以包含Phrasing content元素。

代码实例二:

<div>元素:

所属分类:

(1).Flow content类型元素。[

(2).Palpable content类型元素。

使用场景:

(1).父元素必须是那些子元素为段落式元素的元素。

可以包含的元素:

(1).Flow content。

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

代码实例三:

<a>元素:

所属分类:

(1).Flow content类型元素。

(2).Phrasing content类型元素。

(3).Interactive content类型元素。

(4).Palpable content类型元素。

使用场景:

(1).父元素必须是那些子元素为段落式元素的元素。

可以包含的元素:

(1).子元素是以它的父元素允许的子元素为准,但不能包含交互式元素。

再来看文章开头中提到的代码:

[HTML] 纯文本查看 复制代码
<ul>
  <li>
    <h4><a href=""><div></div></a></h4>
  </li>
</ul>

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

代码修改如下:

[HTML] 纯文本查看 复制代码
<ul>
  <li><div><a href=""><div></div></a></div></li>
</ul>

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

三.嵌套错误可能引起的问题:

开始与结束标签嵌套错误:

[HTML] 纯文本查看 复制代码
<div><h2>内容</div></h2>

测试结果:

4.png

<p>元素嵌套<div>元素:

[HTML] 纯文本查看 复制代码
<p><div>内容</div></p>

测试结果:

5.png

列表元素<li>兄弟元素为<div>:

[HTML] 纯文本查看 复制代码
<ul><li>内容</li><div>内容</div></ul>

测试结果:

6.png

<h2>元素嵌套<div>元素:

[HTML] 纯文本查看 复制代码
<h2><div>内容</div></h2>

测试结果:

7.png

<a>元素嵌套<a>元素:

测试结果:

8.png

通过上面的例子总结如下:

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

(2).在<p>元素内嵌入<div>等元素造成所有浏览器的解析错误。

(3).在<h1>~<h6>元素内嵌入<div>等元素所有浏览器可以解析正常。

(4).在<a>元素内嵌入<a>元素会导致所有浏览器的解析错误。

(5).在列表元素<li><dt><dd>等插入非列表兄弟元素会导致IE6\IE7的解析错误。

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

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

严格嵌套约束规则:

(1).a元素里不可以嵌套交互式元素(<a>、<button>、<select>等)。

(2).<p>里面不可以嵌套<div>、<h1>~<h6>、<p>、<ul>/<ol>/<li>、<dl>/<dt>/<dd>、<form>等。

语义嵌套约束规则:

每个元素基本都有自己的嵌套规则(即父元素可以是什么,子元素可以是什么),除了严格嵌套约束之外的一些规则就是语义嵌套约束,对于语义嵌套约束,如果不遵守,页面可能正常,但也可能解析错误,尽量要遵守,不过也要遵循最佳实践,比如导航菜单经常就会有<ul>元素作为<li>的子元素。



鲜花

握手

雷人

路过

鸡蛋
下一篇:前端规范目的

最新评论

返回顶部