前言

前端程序员在学习HTML的过程中,肯定接触过页面元素的两个基本类型:块状元素和行内元素,也有大量的技术文章或者教程在介绍这两个概念。但这两个HTML元素相关的概念从字面上却和CSS样式有着很深的联系,这种联系有悖于Web规范中一直倡导的表现和样式分离这一核心思想。在HTML5新规范中,已经淡化了元素的这两种分类,取而代之的方案是更具有语义的HTML元素分类方式。在介绍新分类之前,先来谈谈块状元素和行内元素这两个概念。

块元素和行内元素

在W3C制定的HTML4.01规范中,有关内容模型部分详细地介绍了块状元素和行内元素。对于这两种类型的元素,可以从元素在浏览器中的默认渲染样式上来进行区分,块状元素在页面中单独占一行,即display样式的默认值为block,而行内元素则显示在行中,display样式的默认值为inline或者inline-block。

常见的块状元素有:

<div>、<p>、<table>、<ul>、<ol>、<h1>~<h6> 等。常见的行内元素有:<span>、<img>、<a>、<em>、<input>、<select>等。

从默认样式上区分块状元素和行内元素不难,但要理解它们,还得从语义角度出发。块状元素可以包含其它元素,比如p元素可以包含文本和行内元素,<div>可以包含文本、块状元素和行内元素。行内元素表示页面内容,只能包含行内元素,不能包含块状元素。尽管可以通过设置display样式来改变行内元素和块状元素的默认样式,但是其所具有的语义并不会随着样式的更改而更改,即行内元素设置了display样式为block并没有把行内元素更改为块状元素。

从字面意思来看,这两个概念很容易混淆,很多新手并没有深入地理解这两种元素类型的实际含义,所以很多情况下并没有正确的应用,仅仅是从页面布局的角度出发使用块状元素和行内元素。大量的技术文章也误导了很多新手,搜索有关块状元素和行内元素的文章,基本上都是在讨论这两种类型元素的外在默认样式,其实质上讨论的是两个display样式值blockinline的区别。从样式角度理解原生的元素,这有点本末倒置。在前面的章节中反复强调,在构建页面HTML过程中,首先考虑的是语义,判断使用的元素合适与否,就是要判断元素对应的标签是否符合当前元素所要表达的语义,而不是元素的样式是不是更符合当前的UI设计。

HTML5中的定义了内容模型,淡化了块元素和行内元素

为了消除块状元素和行内元素这两个概念引起的混淆,在HTML5规范中刻意淡化了块状元素和行内元素的定义,并按照元素具体的语义重新划分了元素的类型。HTML5中的分类比HTML4.01中的分类更具体,总共分为七类,每种元素并不限定于某一类型,有可能某个元素属于多个类型,以下是具体的分类 :

  • 元数据式内容(Metadata content):<base>、<command>、<link>、<meta>
  • 流式内容(Flow content):<span>、<div>等。这个分类基本包括了HTML4.01中的块状元素和行内元素。
  • 章节式内容:<article>、<aside>、<nav>以及<section>
  • 标题式内容:<h1>~<h6>、<hgroup>
  • 段落式内容:<span>、<img>等。基本上等同于HTML4.01中行内元素的范围。
  • 嵌入式内容:<img>、<iframe>、<svg>、<audio>、<video>、<canvas>等。
  • 交互式内容:<a>、<button>、<select>、<input>等。

规范中还提供了一张各元素类型之间的包含关系图,如图4-11所示。

各元素类型之间的包含关系图

图 HTML5规范中,标签类型关系图

从内容模型上来说,在HTML4.01规范的内容模型部分还规定了块状元素和行内元素中内容的限制,比如行内元素不可以包含块状元素,某些块状元素只能包含行内元素和文字,某些块状元素则可以包含块状元素、行内元素和文字等。更混乱的是在HTML4.01 Transitional模式下和Strict模式下的规则还不完全相同。HTML5规范中结束了这种混乱的局面,并且从实际应用需求出发重新定义了内容模型。举一个例子,假设在页面中有一块区域需要整个添加链接,应该怎么办?a元素在HTML4.01中属于行内元素,按照HTML4.01定义的内容模型规则,行内元素是不能够包含块状元素的,假设区域的HTML代码如下:

<h1>标题<h1>
<div>正文内容</div>

在HTML4.01规范中,只能在<h1>元素和<div>元素内部添加<a>元素,并把文本放置在<a>元素内。

<h1><a href=detail.html>标题</a><h1>
<div><a href=detail.html>正文内容</a></div>

但在HTML5中,可以这样添加:

<a href=detail.html>
    <h1>标题<h1>
    <div>正文内容</div>
</a>

结论

HTML5中<a>元素可以包含块状元素了,这样的定义完全是为了解决现实问题,抛弃了HTML4.01中规定的内容模型。更多有关内容模型的差异,可以查看W3C官网上有关HTML5规范和之前规范的差异的文章

前端开发者在以后的前端开发中无须受这两个概念对应的内容模型规则的束缚,应该结合实际的页面设计需求重新认识HTML5规范中的内容模型,并彻底抛弃块状元素和行内元素这两个概念。

附录