HTML 标签(更准确说叫“元素”)用来描述网页内容的结构与语义,而不是单纯控制样式。一个元素通常由开始标签、内容和结束标签组成,例如<p>段落</p>;也有空元素,如<img>、<br>、<input>,它们没有结束标签。标签名不区分大小写,但建议统一小写。下面按类别列出 HTML Living Standard 中常用标准元素的含义。实验性元素和已废弃元素单独说明。
这一组标签不直接呈现为页面内容,但定义了文档如何被浏览器、搜索引擎和辅助技术理解。
<html> 是根元素,lang 属性声明文档语言,直接影响屏幕阅读器的发音和搜索引擎的语言判断。<head> 是元数据容器,<body> 承载可见内容。
<title> 定义文档标题,显示在浏览器标签、收藏夹和搜索结果标题中,它不同于页面内的 <h1>。<meta> 通过不同属性提供元数据:charset 声明字符编码;name 加 content 提供名称-值对,标准名称包括 description(搜索引擎摘要)、author、keywords、application-name、theme-color、color-scheme 等;http-equiv 则模拟 HTTP 响应头。
<link> 定义当前文档与外部资源的关系,核心在 rel 属性。rel="stylesheet" 引入 CSS;rel="icon" 指定站点图标;rel="canonical" 声明页面的首选 URL;rel="preload"、preconnect、dns-prefetch、modulepreload 用于性能优化,提前加载或连接资源。rel 的值必须是表达语义关系的关键字,不是任意字符串。
<style> 内嵌 CSS;<base> 指定相对 URL 的基准地址和链接默认目标,一个文档只能有一个 <base>。
<script> 是含义最容易误解的标签之一。省略 type、空字符串或 JavaScript MIME 类型时,它是经典脚本;type="module" 使其成为 JavaScript 模块,解析被推迟,charset 和 defer 无效,跨域获取需要 CORS;type="importmap" 时元素体是导入映射 JSON;type="speculationrules" 时是推测规则 JSON;任何其他值则使内容成为数据块,浏览器不执行,src 也被忽略。defer 和 async 只对经典外部脚本有意义,且行为不同。
<noscript> 在脚本不可用时显示;<template> 定义惰性模板,内容不在页面上渲染,供 JavaScript 克隆使用;<slot> 是 Web Components 中分发外部内容的插槽。
<header>、<footer>、<nav>、<main>、<section>、<article>、<aside> 这七个标签构成了 HTML5 语义化结构的骨架。
<header> 是页面或某个区块的头部,常放标题、Logo、导航;<footer> 是页面或区块的页脚,常放版权、联系方式。<nav> 表示主要导航链接区域,不是所有链接组都适合用 <nav>。<main> 是页面主要内容,一个页面通常只应有一个可见的 <main>。
<section> 和 <article> 的区别常被混淆:<section> 是有主题的内容区块,通常应带标题;<article> 是可独立分发或复用的完整内容,例如一篇文章、一条评论、一个论坛帖子。判断标准不是“看起来像卡片”,而是“把它单独拿出去是否仍然有意义”。
<aside> 是与主内容相关但可独立的侧栏、附注、广告或相关链接。<h1>–<h6> 表示标题层级,不代表固定字号,层级不应为了视觉大小而跳级。<hgroup> 将标题与其副标题、标语分组。<address> 表示最近文章或页面所属的联系信息,不是任意地址。
<div> 是无语义的通用块级容器;<p> 是段落;<hr> 表示段落级话题转换,不是视觉分隔线。<pre> 保留空格和换行,常与 <code> 搭配表示代码块。
<blockquote> 是块级引用,可配合 cite 属性提供来源 URL;<q> 是行内短引用,浏览器通常自动加引号。<ol>、<ul>、<li> 分别是有序、无序列表和列表项;<menu> 也可容纳 <li>,语义上表示命令列表。
<dl> 是描述列表,由 <dt>(术语)和 <dd>(描述)组成,适合术语表、元数据对、问答。<figure> 是独立插图、图表、代码等可配说明的内容,<figcaption> 是其标题或说明。
文本级语义标签的价值在于它们告诉机器“这段文字是什么”,而不仅仅是“看起来什么样”。
<em> 表示强调重音,<strong> 表示重要性或严重性;二者语义不同,默认样式只是表象。<b> 用于引起注意但不表示强调,<i> 用于不同语气、术语、外语等,<u> 用于非文本注释(如拼写错误标记)。<s> 表示内容不再准确或不再相关,<del> 表示文档中已删除的内容,<ins> 表示已插入的内容;<del> 和 <ins> 可以用 cite 和 datetime 记录修改来源和时间。
<small> 是附属小字,如版权、法律声明。<mark> 是相关性高亮,不同于强调。<code> 是代码片段,<var> 是变量,<samp> 是程序输出,<kbd> 是用户键盘输入。<sub> 和 <sup> 是上下标。<abbr> 表示缩写,title 属性可提供全称;<dfn> 是术语的定义实例。<cite> 表示作品标题(书名、文章名、电影名),不是作者名。
<ruby> 用于注音或拼音标注,内部由 <rt> 提供注音文本,<rp> 在不支持 ruby 的浏览器中显示括号。<data> 给内容附加机器可读值,<time> 用 datetime 提供机器可读日期时间。<bdi> 隔离双向文本,<bdo> 覆盖文本方向。<span> 是无语义行内容器;<br> 是换行;<wbr> 是可选换行机会。
<img> 嵌入图片,alt 提供替代文本;srcset 和 sizes 用于分辨率切换。<picture> 是响应式图片容器,包含零个或多个 <source> 和一个 <img>,浏览器按 media、type、srcset 选择最合适的源,全部不匹配时回退到 <img> 的 src。它主要用于“艺术指导”(不同屏幕裁剪不同构图)和“格式回退”(如优先 AVIF/WebP,不支持时用 JPEG)。
<video> 和 <audio> 嵌入媒体,<source> 提供候选源,<track> 提供字幕、说明、章节等文本轨道。<map> 和 <area> 定义客户端图像映射。<canvas> 是通过 JavaScript 绘制位图的画布。<iframe> 嵌入另一个浏览上下文。<embed> 和 <object> 嵌入外部内容,<object> 还可包含回退内容。<svg> 嵌入 SVG 矢量图形,<math> 嵌入 MathML 数学公式。
<table> 表示多维数据,不是布局工具。<caption> 是表格标题,应紧跟在 <table> 开始标签之后,对屏幕阅读器用户尤其重要。<colgroup> 和 <col> 定义列组和列属性。<thead>、<tbody>、<tfoot> 分别标记表头、表体、表尾区域,它们的价值在于为 CSS 和打印提供结构钩子,而不是自动提升可访问性。<tr> 是行,<th> 是表头单元格,<td> 是数据单元格。<th> 的 scope 属性(col、row、colgroup、rowgroup)能帮助辅助技术建立单元格与表头的对应关系,是表格可访问性的关键。
<form> 是表单容器。<label> 是控件说明,通过 for 与控件 id 关联,或包裹控件,点击标签即可聚焦控件;这是表单可访问性的基础。<input> 是功能最复杂的元素,含义完全由 type 决定:
<button> 是按钮,type 有 submit、reset、button;不写 type 时在表单内默认为 submit,容易导致意外提交。<select> 是下拉或多选列表,<option> 是选项,<optgroup> 是选项组,<datalist> 为输入框提供预选建议。<textarea> 是多行文本,<output> 是计算结果输出,<progress> 是任务进度,<meter> 是已知范围内的标量度量。<fieldset> 分组表单控件,<legend> 是分组的标题。
<details> 是可展开/收起的详情组件,<summary> 是其摘要,点击摘要切换展开状态。<dialog> 是对话框,配合 showModal() 可成为模态窗口,原生提供焦点管理和关闭行为。
全局属性可用于所有 HTML 元素,即使元素本身没有专门定义它们。它们不改变标签的类别,但深刻影响元素的行为与可访问性。
id 定义文档内唯一标识,是 CSS、JavaScript、<label for>、aria-labelledby 和片段导航的锚点。class 是空格分隔的类名列表,主要供 CSS 和 JavaScript 选择。style 内联样式。title 提供咨询信息,常在悬停时显示,但不应作为关键信息的唯一载体。lang 声明内容语言,dir 声明文本方向(ltr、rtl、auto)。hidden 隐藏元素。tabindex 控制键盘焦点顺序。contenteditable 使元素内容可编辑。draggable 和 dropzone 涉及拖放。accesskey 定义键盘快捷键。spellcheck 控制拼写检查。translate 提示是否翻译。
ARIA 相关:role 和 aria-* 属性可用于补充或覆盖元素的隐式语义。HTML 元素本身已经带有隐式 ARIA 语义——<a href> 隐含 link,<button> 隐含 button,<nav> 隐含 navigation。原则是:能用原生 HTML 元素表达语义时,不要用 <div role="..."> 去模拟;显式写出与隐式语义相同的 role 通常不推荐,除非需要兼容不暴露隐式语义的用户代理。
事件处理属性(onclick、oninput、onsubmit、onkeydown、onload、onerror 等)本质上也是全局属性,但现代开发通常用 addEventListener 分离行为。
HTML Living Standard 将一些元素列为完全废弃、作者不得使用,并给出了明确的替代方案:applet 用 embed 或 object;acronym 用 abbr;bgsound 用 audio;dir 用 ul;frame、frameset、noframes 用 iframe 加 CSS 或服务端包含;isindex 用显式表单加文本字段;listing 用 pre 加 code;plaintext 用 text/plain MIME 类型;rb 直接省略;strike 表示编辑用 del,否则用 s;xmp 用 code 并转义;basefont、big、blink、center、font、marquee、multicol、nobr、spacer、tt 用适当的元素或 CSS 替代。
此外,<table> 的 summary 属性已弃用,应改用 <caption>;<img> 的 border、<a> 的 name(应改用 id)等表现性或过时属性也不应再使用。
第一,标签表达语义,不是外观。 <strong> 与 <b>、<em> 与 <i>、<del> 与 <s> 的默认样式相似,但语义不同;不要用标签代替 CSS。
第二,优先使用语义化元素,少用无意义的 <div>。 能用 <nav>、<main>、<article>、<button>、<label> 表达的结构,不要用 <div> 加 role 模拟。语义化标签直接给搜索引擎和辅助技术提供“机器能看懂的结构说明书”。
第三,表单可访问性不是可选项。 每个输入控件都应有可关联的 <label>;按钮用 <button> 而不是可点击的 <div>;表格数据用 <th> 并配合 scope;图片写 alt;标题层级不要跳级。
第四,理解元素的“内容模型”。 某些元素对子元素有严格限制:<ul> 和 <ol> 的直接子元素应是 <li>;<table> 有特定的行组结构;<p> 内不能嵌套块级元素。违反内容模型会导致浏览器解析出意料之外的 DOM。
第五,区分“已废弃”与“不推荐”。 废弃元素是标准明确禁止使用的;另一些做法虽未被禁止,但已有更好的语义替代(如用 <div role="button"> 代替 <button>),应优先选择原生语义。
HTML 的标签体系本质上是一套关于内容是什么的声明。掌握每个标签的含义,不只是记住它的默认样式,而是理解它向浏览器、搜索引擎、屏幕阅读器和其他开发者传递了什么信息;而属性、全局属性和 ARIA 则是在这个语义骨架上做精确补充的层次。