HTML 标签详解
HTML(HyperText Markup Language,超文本标记语言)给网页里的内容赋予含义和结构。CSS 管表现,JavaScript 管行为和功能。浏览器认出标题、段落、表单,靠的是标签选得对,而不是后来改的 display。
「超文本」(hypertext)指把单个站点内、或站点之间的页面连起来的链接。链接是网络的基本方面。把内容放到网上,并与他人创建的页面相链接,就成为万维网的参与者。
HTML 使用「标记」(markup)注明文本、图片和其他内容,以便在 Web 浏览器中显示。标记由「元素」组成,常见的有:
head、title、body、header、footer、article、section、p、div、span、img、aside、audio、canvas、datalist、details、embed、nav、output、progress、video
HTML 元素通过「标签」(tag)把内容从文档里标出来。标签由包在 < 和 > 里的元素名组成。HTML 里的元素名不区分大小写,大写、小写或混合书写都可以。作为 XML 解析的 XHTML 则必须按 XML 规则匹配大小写。
元素按内容分类
每一个 HTML 元素都必须遵循「它可以包含哪一类内容」的规则。这些规则被归成几种常见的内容模型(content model)。每个 HTML 元素属于 0 个、1 个或多个内容类别,嵌套必须符合 HTML 规范。
内容分类大致有三类:
- 主内容类:很多元素共享的内容规范
- 表单相关的内容类:表单相关元素共有的内容规范
- 特殊内容类:只在某些特殊元素上才要遵守的规范,通常和特定上下文有关
HTML5 不再用 DTD 把标签分成「块级、行内」来约束嵌套。嵌套合不合法,看的是下面这些内容类别;默认是块还是行内,看的是 CSS 的 display。
主内容类(Main content categories)
元数据内容(Metadata content)
此类元素修改文档其余部分的陈述或行为,建立与其他文档的链接,或传达其他外带信息。
base、link、meta、noscript、script、style、template、title
流式内容(Flow content)
此类元素通常包含文本或植入的内容。有的资料译成「流式元素」。
所有可以放在 <body> 里、构成文档内容的元素均属于流式内容。因此,除了只能放在 <head> 里的元数据内容(base、link、meta、style、title 等)之外,剩下的元素大多属于流式内容。noscript、script、template 在 <head> 和 <body> 里都可以出现,类别随位置变化。
a、abbr、address、article、aside、audio、b、bdo、bdi、blockquote、br、button、canvas、cite、code、data、datalist、del、details、dfn、div、dl、em、embed、fieldset、figure、footer、form、h1~h6、header、hgroup、hr、i、iframe、img、input、ins、kbd、label、main、map、mark、math、menu、meter、nav、noscript、object、ol、output、p、pre、progress、q、ruby、s、samp、script、section、select、small、span、strong、sub、sup、svg、table、template、textarea、time、ul、var、video、wbr、文本节点
属于此类、但仅限于某种特殊情形的元素:
area:仅限于它作为map的子节点的情形link、meta:当itemprop属性存在时(微数据),可以出现在<body>里,从而也算流式内容
章节内容(Sectioning content)
属于分节内容模型的元素会在当前大纲中创建一个分节,此分节将定义 header、footer 和标题元素的范围。
article、aside、nav、section
header、footer 不是章节内容。它们是章节里的页眉、页脚,自己不新开一个大纲分节。
标题内容(Heading content)
标题内容定义了分节的标题。这个分节可以由一个明确的分节内容元素直接标记,也可以由标题本身隐式地定义。
h1~h6、hgroup(将多个 h1~h6 的子元素组装到一起)
短语内容(Phrasing content)
短语内容规定文本和它包含的标记。有的资料译成「段落元素」,容易和 <p> 混淆;规范英文是 Phrasing content。
所有可以放在 <p> 里、构成段落内容的元素均属于短语内容。因此,所有短语内容也都属于流式内容。
abbr、audio、b、bdo、br、button、canvas、cite、code、datalist、dfn、em、embed、i、iframe、img、input、kbd、label、mark、math、meter、noscript、object、output、progress、q、ruby、samp、script、select、small、span、strong、sub、sup、svg、textarea、time、var、video、wbr、文本节点
一些其他元素也属于这个分类,但只有在如下特殊情况时才算:
a、del、ins、map:当它仅包含短语内容时area:当它为map元素的子元素时link、meta:当itemprop属性存在时
嵌入内容(Embedded content)
嵌入内容把另一个资源嵌进来,或把另一种标记语言、命名空间的内容插入文档。
audio、canvas、embed、iframe、img、math、object、picture、svg、video
交互内容(Interactive content)
交互式内容包含为用户交互而特别设计的元素。
a、button、details、embed、iframe、label、select、textarea
仅在特殊情形下才会属于此类的元素有:
audio、video:当controls属性存在时img、object:当usemap属性存在时input:当type属性不处于隐藏(hidden)状态时
表单相关内容(Form-associated content)
表单相关内容包含拥有表单所有者(form owner)的元素。所有者可以是祖先里的 <form>,也可以是 form 属性里写的那个表单 id。
button、fieldset、input、label、meter、object、output、progress、select、textarea
另外,还存在一些较小的分类,如脚本支持元素(Script-supporting elements):
script、template
透明内容模型(Transparent content model)
如果一个元素拥有透明内容模型,它的内容模型跟父元素走:父元素里允许放什么,它里面就可以放什么。把该元素「揭掉」,剩下的子节点在父元素里仍然必须是合法 HTML。
del、ins
a 在只包短语内容时按短语内容算;若包的是流式内容,则常常按透明模型处理。不要把透明理解成「里面随便放」。
元素按功能分组
下面按用途归组,和 MDN 的 HTML 元素参考一致,方便按场景找标签。同一元素可以同时属于上一节的某个内容类别。
主根元素
主根元素表示一个 HTML 文档的根(顶级元素),所以它也被称为根元素。所有其他元素必须是此元素的后代。
html
文档元数据
元数据含有页面的相关信息,包括样式、脚本及数据,能帮助搜索引擎、浏览器等更好地运用和渲染页面。样式和脚本的元数据可以直接写在网页里,也可以链接到外部文件。
base、head、link、meta、noscript、script、style、title
分区根元素
分区根元素表示文档的内容。
body
内容分区
内容分区元素允许将文档内容从逻辑上组织划分。使用页眉(header)、页脚(footer)、导航(nav)和标题(h1~h6)等分区相关元素,来为页面内容创建明确的大纲,以便区分各个章节。
article、section、header、h1~h6、main、nav、aside、footer、address
文本内容
使用文本内容元素来组织 <body> 内的块或章节。这些元素能标识内容的宗旨或结构,对可访问性(accessibility)和搜索引擎优化(SEO)很重要。
blockquote、div、dl、dt、dd、figcaption、figure、hr、li、menu、ol、p、pre、ul
内联文本语义
使用内联文本语义元素定义一个单词、一行内容,或任意文字的语义、结构或样式。
a、abbr、b、bdi、bdo、br、cite、code、data、dfn、em、i、kbd、mark、q、rp、rt、ruby、s、samp、small、span、strong、sub、sup、time、u、var、wbr
图片和多媒体
HTML 支持各种多媒体资源,例如图像、音频和视频。
area、audio、img、map、track、video
内嵌内容
除了常规的多媒体内容,HTML 可以包括各种其他内容,即使它并不容易交互。
embed、iframe、object、picture、source
SVG 和 MathML
使用 svg、math 标签将 SVG 或 MathML 内容直接嵌入 HTML 文档。
svg、math
脚本
为了创建动态内容和 Web 应用程序,HTML 支持使用脚本语言,最突出的就是 JavaScript。
canvas、noscript、script
canvas 本身是绘图表面,通常由脚本驱动,所以归在这一组。
编辑标识
这些元素能标示出某个文本被更改过的部分。
del、ins
表格内容
这里的元素用于创建和处理表格数据。
caption、col、colgroup、table、tbody、td、tfoot、th、thead、tr
表单
HTML 提供了许多可一起使用的元素,用来创建一个用户可以填写并提交到网站或应用程序的表单。
button、datalist、fieldset、form、input、label、legend、meter、optgroup、option、output、progress、select、textarea
交互元素
HTML 提供了一系列有助于创建交互式用户界面对象的元素。
details、dialog、summary
Web 组件
Web 组件是一种与 HTML 相关联的技术。它允许开发者创建自定义元素,并如同普通的 HTML 一样使用它们。另外,也可以创建经过自定义的标准 HTML 元素。
slot、template
行内元素和块级元素
在 CSS 里,元素按盒的生成方式常分成块级和行内(还有行内块等)。这些默认表现曾经写在 HTML 的 DTD 里;现行 HTML 用内容类别约束嵌套,用用户代理样式表给出默认 display。日常说「div 是块级、span 是行内」,指的就是这套默认 CSS。
块级元素
HTML 中,总是从新行开始,并且占据可用的整个宽度(尽可能向左和向右伸展)的元素,称为块级元素。
div、p、hr、h1~h6、
ul、ol、li、dl、dt、dd、
table、caption、thead、tbody、tfoot、tr、th、td、
form、fieldset、legend、
noscript、pre、address
块级元素有以下特点:
- 总是从新行开始
- 宽度缺省是它的容器的 100%,除非设定一个宽度(
width: auto时块盒会拉满包含块) - 宽、高、行高以及外边距和内边距都可控制
- 可以容纳内联元素和其他块元素(还要同时满足内容类别,例如
<p>里不能再放块级元素)
注意:在
<p>元素中不能嵌套块级元素。<p>还没结束时,遇到下一个块级元素就会自动结束。<p> <div>p标签不能放块元素。</div> </p>在浏览器中渲染为:
<p></p> <div>p标签不能放块元素。</div> <p></p>
行内元素
HTML 中,不会从新行开始,并且只占用必要宽度的元素,称为行内元素。
span、a、b、em、i、small、strong、sub、sup、img、input、select、textarea、br、
abbr、bdo、cite、code、dfn、kbd、q、samp、var
行内元素有以下特点:
- 元素不会从新行开始
- 非替换行内元素(如
span、em)只占用内容需要的宽度,设width、height无效 - 非替换行内元素的上下外边距不参与行框高度计算;上下内边距可以加大背景范围,但不把周围行撑开
- 左右外边距、左右内边距有效
- 只能容纳文本或者其他内联元素(嵌套块级元素时,行内盒的高度不会按块级子元素去撑)
img、input、select、textarea等替换元素(replaced element)可以设置宽高,不要和普通span混为一谈
行内块元素
行内块既具有块级元素的特点,也有行内元素的特点。它可以设置宽、高、行高、外边距、内边距,也可以和其他行内或行内块元素放在同一行上。
行内元素和块级元素都可以通过 CSS 的 display: inline-block 转换成行内块。
行内元素和块级元素的区别
- 排列方式:块级元素独占一行,默认宽度自动填满父元素;行内元素不独占一行,相邻的会排在同一行,宽度随内容变化。
- 包含关系:块级元素可以包含行内元素和(在内容类别允许时)块级元素;行内元素不能包含块级元素。
- 盒尺寸:块级元素可以设置宽、高、行高、外边距、内边距。非替换行内元素不能设置宽、高和上下外边距;左右外边距、左右内边距可以。
不管块级、行内还是行内块,区别主要是三个方面:排列方式、默认宽度、宽高边距能否设置。嵌套能不能写,仍以内容类别为准。
HTML 标签嵌套
HTML 中为何 p 标签内不可包含 div 标签
也可以通过 CSS 把 div 定义成内联、把 span 定义成块,但是不能在 HTML 里靠改 display 改变内容模型。块级元素可以包含内联元素或某些块元素,内联元素不能包含块元素,只能包含其他内联元素。
因为所用的内容模型规定块级元素不能放在 <p> 里面(<p> 只接受短语内容)。再加上浏览器会纠正这种写法:
<p>这是一个段落的开始
<p>这是另一个段落的开始
<!-- 当一个 <p> 还没结束时,遇到下一个块元素就会把自己结束掉,浏览器会处理成: -->
<p>这是一个段落的开始</p>
<p>这是另一个段落的开始</p>
哪些块元素里面不能放哪些块元素
可以把块元素再划成几个级别。html 在最外层;html 下一级里是 head、body。可视内容出现在 body 里,所以把 body 划在第一级;把不可以自由嵌套的元素划在第三级,其他归进第二级。
所谓不可自由嵌套的元素,就是里面只能放内联(短语)内容的,包括:
- 标题标记:
h1~h6、caption - 段落标记:
p - 其他:
hr、dt(只作为dl的子元素)
为什么说第二级的元素可以自由嵌套
可以把它们看成容器(盒子),大小可以变化。例如可以把 ul 嵌在 div 里面,也可以把 div 嵌在 li 里面。
在 HTML 里有几个元素比较特别,ul、ol、dl、table 的子一层必须是指定元素:
ul、ol的子一级必须是lidl的子一级必须是dt、ddtable的子一层必须是caption、thead、tfoot、tbody等;再下一层必须是tr(位于thead、tfoot、tbody中,或作为table的直接子元素由浏览器补全);之后才是可放内容的td、th
其他元素特点
空元素
标签内没有内容的 HTML 标签被称为空元素。空元素没有结束标签,在开始标签处关闭。例如:br、hr、img、input、link、meta。还有 area、base、col、embed、source、track、wbr 等。
link 标签
link 定义文档与外部资源的关系。常见用法是写在 <head> 里。
rel 属性定义当前文档与被链接文档之间的关系。常见的 stylesheet 表示加载外部样式表。
HTML5 里,带 itemprop 的 link,以及部分「对 body 合法」的 rel(如预加载类),也可以出现在 <body> 中。
常见问题
1. HTML5 有哪些新特性、移除了哪些元素?
HTML5 现在已经不是 SGML 的子集,主要增加了图像、位置、存储、多任务等方面的能力。其中不少是配套的 Web API,不是新标签本身。
新增或当时一并宣传的有:
- 绘画
canvas - 用于媒介回放的
video和audio元素 - 本地离线存储
localStorage:长期存储数据,浏览器关闭后数据不丢失 sessionStorage:数据在浏览器关闭后自动删除- 语义化更好的内容元素,比如
article、footer、header、nav、section - 表单控件:
date、time、datetime-local、email、url、search,以及datalist、output Web Worker、WebSocket- 文档属性
document.visibilityState(Page Visibility API)
移除的元素有:
- 纯表现的元素:
basefont、big、center、font、s、strike、tt、u - 对可用性产生负面影响的元素:
frame、frameset、noframes
其中 s、u 后来又以新语义回到规范(不再准确的内容、需标注的文本),不要再拿它们当单纯的加粗、下划线来用。
2. 如何处理 HTML5 新标签的浏览器兼容问题?
IE8、IE7、IE6 支持通过 document.createElement 方法产生的标签。可以利用这一特性让这些浏览器识别 HTML5 新标签;识别之后,还需要补上标签的默认样式。
也可以直接使用成熟的补丁,比如 html5shiv:
<!--[if lt IE 9]>
<script src="https://cdn.jsdelivr.net/npm/html5shiv/dist/html5shiv.min.js"></script>
<![endif]-->
[if lt IE 9]……[endif] 是条件注释,限定只有 IE 9 以下才加载这段脚本。有的说明写成 lte IE 9,和上面这条「小于 9」的写法不是同一范围。
4. HTML 语义化的理解
- 用正确的标签做正确的事情。
- HTML 语义化让页面的内容结构化,结构更清晰,便于浏览器、搜索引擎解析。
- 即使在没有样式 CSS 的情况下也以一种文档格式显示,并且容易阅读。
- 搜索引擎的爬虫也依赖于 HTML 标记来确定上下文和各个关键字的权重,利于 SEO。
- 使阅读源代码的人更容易将网站分块,便于阅读、维护、理解。
HTML 的本质作用是定义网页文档的结构。一个语义化的文档能使页面结构更清晰,既利于开发者维护,也利于机器正确解读。
如果是搜索引擎的爬虫来分析网页,它会依赖 HTML 标签来确定上下文和关键字权重。语义化的文档对爬虫友好,有利于解读,从而有利于 SEO。从 HTML5 可以看出,标准倾向于以语义化的方式构建网页,比如新增了 header、footer 这些语义标签。
5. b 与 strong 的区别和 i 与 em 的区别?
从页面显示效果来看,被 b 和 strong 包围的文字将会被加粗,而被 i 和 em 包围的文字将以斜体呈现。
b、i 是自然样式标签,分别表示无额外重要性的加粗、无额外强调的斜体,表现接近 { font-weight: bolder } 和斜体,仅仅表示「这里应该用粗体显示」或「这里应该用斜体显示」。这两个标签在 HTML 4.01 中并不被推荐当作语义手段。
em、strong 是语义样式标签。em 表示一般的强调(重音、语气),strong 表示更强的重要性。
使用辅助技术阅读网页时,em、strong 带有强调语义,读屏会按强调来读;b、i 通常只影响视觉。不要把「会重读」理解成所有读屏软件的统一行为。
现行用法:关键词、产品名用 b;重要性用 strong;科技术语、心声、外语用 i;一句话里要重读的词用 em。外观一律交给 CSS。
6. title 与 h1 的区别?
这里比较的是 <title> 和 <h1>,不是元素上的 title 属性。
<title>写在<head>里,给整份文档起名,出现在浏览器标签页、搜索结果标题、收藏夹里,不在页面正文中显示。<h1>是正文里层次明确的标题,参与文档大纲,对页面信息抓取和可访问性影响大。
一份文档通常一个有意义的 <title>,正文里的 <h1> 则对应页面主标题,两者内容可以相近,职责不同。
7. 页面导入样式时,使用 link 和 @import 有什么区别?
- 从属关系:
@import是 CSS 提供的语法规则,只有导入样式表的作用;link是 HTML 提供的标签,不仅可以加载 CSS 文件,还可以定义 RSS、rel关系、引入网站图标等。 - 加载时机:写在 HTML 里的
<link rel="stylesheet">在解析 HTML 时就能被发现并开始下载。写在 CSS 文件里的@import要等这份 CSS 下载并解析之后才会被发现,因此更晚开始,容易拖后渲染。不是「等整个页面加载完毕才加载」。 - DOM 可控性:可以通过 JavaScript 操作 DOM,插入
link标签来改样式。没有专门的「插入@import」的 DOM 接口;虽然能往<style>文本里写@import,但发现和下载仍晚于等价的link。
8. iframe 有哪些缺点?
iframe会阻塞主页面的onload事件。window的onload需要在所有iframe加载完毕后(包含里面的元素)才会触发。在 Safari 和 Chrome 里,通过 JavaScript 动态设置iframe的src可以避免这种阻塞。- 搜索引擎对框架里的页面解读较弱,不利于把框架页当作主内容做 SEO。
iframe和主页面共享连接池。HTTP/1.1 下浏览器对相同域的并行连接有限制,因此会影响页面的并行加载。HTTP/2、HTTP/3 下同域多路复用,这条没有以前严重。- 部分环境下后退行为不符合预期(视历史记录如何写入),不是所有浏览器都「后退按钮失效」。
- 小型移动设备上框架布局难以完整展示,触控和视口也不如普通文档好处理。
9. HTML 中为何 p 标签不可包含块元素?
在 HTML5 中,标准重新定义了 HTML 元素的分类:所有可以放在 <p> 内、构成段落内容的元素均属于短语内容。块级元素不属于短语内容,因此不能放在 <p> 里。
<p> 内包含块元素时,它会先结束自己。
<section class="box_08">
<p>
黄叶青苔归路,屧粉衣香何处。消息竟沉沉,今夜相思几许。
<div>秋雨,秋雨,一半因风吹去。—纳兰性德-如梦令</div>
</p>
</section>

10. head 标签中必不可少的是?
head 用于定义文档的头部,它是所有头部元素的容器。head 中的元素可以引用脚本、指示浏览器在哪里找到样式表、提供元信息等等。
文档的头部描述了文档的各种属性和信息,包括文档的标题、在 Web 中的位置以及和其他文档的关系等。绝大多数文档头部包含的数据都不会真正作为内容显示给读者。
下面这些标签可用在 head 部分:base、link、meta、script、style、title。
title 定义文档的标题,它是 head 部分中规范要求必须出现的元素(另有 iframe 的 srcdoc 等少数例外)。
注意:Chrome 实测,源码里不写 <head> 标签,页面也能显示。HTML 解析器会补出隐含的 head。这不表示可以省略 <title>。
结语
选标签先看内容和功能:嵌套跟内容类别走,版面跟 CSS 的 display 走。语义写对,浏览器、辅助技术和搜索引擎才读得懂;p 里塞 div 这类错误,引擎会直接改掉你的树。