Skip to content

易错语义

基于 HTML Living Standard · 核于 2026-06

速查

  • <search>:搜索 / 筛选区的语义容器,自带 search 地标,取代 <div role="search">2023-10 起 Baseline 广泛可用
  • <search> 包的是搜索控件(表单、输入框),不是搜索结果——结果属于正文
  • <address>:只表示「最近的 <article> / <body>」的联系方式不是「任意邮政地址」标签
  • <address>塞发布日期(用 <time>)、别塞非联系信息;不能嵌套 <address>
  • <hgroup> 语义已变:现在是「一个 <h1><h6> + 若干 <p>(副标题 / 标语)」,不再是「包多个标题」
  • <hgroup> 不影响大纲,进大纲的只有里面那唯一的标题;<p> 副标题不计层级
  • 三者共同点:都有「看着像、其实不是」的误用陷阱——按含义用,别按外观套

这三个元素都属于「知道的人不多、用错的人不少」。共同的坑是它们看起来能套在很多地方,实际语义却很窄。

<search>:搜索区的语义容器(新)

它是什么

<search> 在语义上标明「这块内容是搜索 / 筛选功能」。MDN 的定义:

<search> 元素在语义上把其内容标识为具备搜索或筛选能力。这种能力可以面向整个网站 / 应用、当前页面 / 文档,或者整个互联网的某个子集。」

它的隐式角色是 search 地标。这正是它最大的价值——取代手写的 role="search"

html
<!-- 旧写法:div + role -->
<div role="search">
  <form action="/search">…</form>
</div>

<!-- 新写法:语义元素,自带 search 地标 -->
<search>
  <form action="/search">
    <label for="q">站内搜索</label>
    <input type="search" id="q" name="q" />
    <button type="submit">搜索</button>
  </form>
</search>

关键陷阱:包控件,不包结果

最常见的误解是把搜索结果也塞进 <search>。MDN 说得很明确:<search> 用于搜索的控件与功能不用于呈现搜索结果——结果应当属于页面的主内容。<search> 内部可以放的是「即时搜索建议」这类紧贴搜索框的东西。

一页可以有多个 <search>(站点搜索 + 列表筛选),同样用 title / aria-label 区分:

html
<header>
  <search title="站内搜索">…</search>
</header>
<main>
  <h2>可租车辆</h2>
  <search title="筛选车辆">
    <h3>筛选条件</h3>

  </search>
  <article><!-- 这里才是结果 --></article>
</main>

兼容性:Baseline 广泛可用(2023-10)

<search> 的 Baseline 状态

<search>较新的元素:自 2023 年 10 月起达到 Baseline 广泛可用(Chrome / Edge / Firefox / Safari 现代版本均支持)。对绝大多数现代项目可以放心使用。若必须兼容这之前的老浏览器,降级方案是退回 <div role="search">——语义地标等价,只是少了元素本身的明确性。

<address>:联系方式,不是「地址标签」

它真正的含义

<address> 几乎是被误用最多的语义元素。它的真正含义不是「任何一段邮政地址」,而是:

「为其最近的 <article><body> 祖先提供联系方式。」

「联系方式」可以是物理地址、URL、邮箱、电话、社交账号、地理坐标——只要是「联系到这个人 / 组织」的信息。判定它该不该用,看的是「这是不是本文 / 本站的联系方式」,而不是「这段文字里有没有地址」。

html
<footer>
  <address>
    你可以通过 <a href="https://example.com/contact">example.com</a> 联系作者,
    发现 bug 请 <a href="mailto:webmaster@example.com">联系站长</a>。
  </address>
</footer>

它的隐式角色是 group,习惯上放在当前区段的 <footer> 里。

三条「别」

  • 拿它包「与联系无关的任意地址」。比如文章正文里提到「故宫位于北京市……」,那是普通内容,不是 <address>
  • 往里塞发布日期等元信息——MDN 明确:日期属于 <time>,不该混进 <address>
  • 嵌套 <address>,也别在 <address> 里放 <article> / <aside> / 标题等分区内容。
html
<!-- ❌ 误用:这只是文中提到的一个地址,不是联系方式 -->
<p>展览地点:<address>北京市东城区景山前街 4 号</address></p>

<!-- ❌ 误用:发布日期不该进 address -->
<address>作者 Tom,发表于 <time datetime="2026-06-24">2026-06-24</time></address>

<!-- ✅ 正确:本文 / 本站的联系方式 -->
<address>作者:<a href="mailto:tom@example.com">tom@example.com</a></address>

还有一个细节:<address> 代表的是最近的 <article> / <body> 的联系方式。所以在「文章 + 嵌套评论」结构里,写在外层文章的 <address> 不会自动适用于嵌套的评论 <article>

<hgroup>:语义已经变了

现在的正确用法

<hgroup> 是个「语义被悄悄改过」的元素,很多老资料还停留在旧定义。它现在的含义是:

「把一个 <h1><h6> 元素,与一个或多个 <p> 组合在一起。」

具体内容模型是:零个或多个 <p>恰好一个标题 → 零个或多个 <p>。也就是说,它用来给单个标题配上副标题 / 标语 / 别名(用 <p> 承载):

html
<hgroup>
  <h1>科学怪人</h1>
  <p>又名:现代普罗米修斯</p>
</hgroup>
<p>瑞士科学家维克多·弗兰肯斯坦怀有一个宏大的抱负:创造智慧生命……</p>

它过去是什么、为什么别再那么用

历史上<hgroup> 是用来把多个标题元素(如 <h1><h2> / <h3>)组合起来表示「主标题 + 副标题」的。这个旧用法已被废弃,现在改成了「一个标题 + 若干 <p>」的设计。

html
<!-- ❌ 旧的、已废弃的用法:包多个标题 -->
<hgroup>
  <h1>主标题</h1>
  <h2>副标题</h2>
</hgroup>

<!-- ✅ 现在的用法:标题 + p 副标题 -->
<hgroup>
  <h1>主标题</h1>
  <p>副标题</p>
</hgroup>

如果你还在用旧写法,副标题 <h2> 会被当成一个真正的二级标题进入大纲,污染层级结构。

它和文档大纲的关系

<hgroup> 本身对文档大纲没有任何影响——MDN:「<hgroup> 自身不影响网页的文档大纲,影响大纲的是其中那个唯一允许的标题。」里面的 <p> 副标题不计入标题层级。它的隐式角色是 group。这一点和 标题层级与文档大纲 里讲的「只有真标题才进大纲」一脉相承。

三者对照

元素真正含义最常见误用Baseline
<search>搜索 / 筛选控件区(search 地标)把搜索结果也塞进去✅ 2023-10 广泛可用
<address>最近 <article>/<body>联系方式拿来包任意邮政地址 / 发布日期✅ 广泛可用
<hgroup>一个标题 + 若干 <p> 副标题沿用旧法包多个标题✅ 广泛可用

下一步

分区与标题之外,还有一类「内容级」的语义元素——把段落、引用、图表、分隔线组织起来的 p·blockquote·figure·figcaption·hr·pre,以及作为最后手段的 div分组内容