HTML5引入的语义化标签中,<header>是使用频率最高、也最容易用错的标签之一。很多开发者把header简单理解为“页面顶部的那个区域”,于是用<div id="header">和<header>混着写,甚至完全忽略这个标签的存在。实际上,header承载的语义是“介绍性内容的容器”,它既可以是整个页面的页头,也可以是文章、章节甚至侧边栏内部的小标题区域。理解这一点,是写出规范语义化结构的前提。

header标签的语义边界:页面内任意区块的头部
要弄清楚header的正确用法,首先需要纠正一个普遍认知:header并不是页面顶部的专属容器。HTML标准对<header>的定义是“代表最近一节(section)的引导性内容”,它通常包含一组标题(h1到h6元素)、导航链接、Logo、搜索框、作者信息等。也就是说,只要某个内容区块需要一组介绍性的信息放在最前面,就可以使用header标签包裹。
举个例子,在博客文章页面的结构中,整篇<article>的顶部通常会放文章标题、作者、发布时间和分类标签,这些内容完全可以用一个<header>包起来。同样,侧边栏的“热门文章”模块,如果需要一个标题栏包裹在模块顶部,使用<header>也是合理的。header的语义是相对于“它所在的区块”而言的,它标识的是“这一块内容的开头”而不是“整个页面的开头”。
页面顶部那个最常见的全站页头,在HTML语义化术语中叫做“页面级页头”(page header),它通常包含网站Logo、主导航、搜索入口等全站性信息,用<header>包裹是标准做法。但关键在于,在一个HTML文档中,<header>标签的使用次数没有限制,每个独立的区块都可以有自己的header,只要内容逻辑上成立。下面展示一个典型的页面结构:
<body>
<!-- 全站页头 -->
<header>
<a href="/"><img src="logo.png" alt="网站Logo" /></a>
<nav>
<ul>
<li><a href="/home">首页</a></li>
<li><a href="/blog">博客</a></li>
</ul>
</nav>
</header>
<main>
<article>
<!-- 文章区块自己的头部 -->
<header>
<h1>HTML语义化header标签彻底讲清楚</h1>
<p>作者:小明 | 发布于:2024年1月 </p>
</header>
<p>正文内容……</p>
</article>
</main>
<footer>版权信息</footer>
</body>
注意观察上面代码中两个<header>的区别:第一个是全站性质的页头,第二个是文章区的头部。这两个header虽然标签名相同,但语义层级完全不同。浏览器和搜索引擎可以通过最外层section(这里由body隐式承担)以及header在DOM中的位置,自动判断它们的层级关系,不需要开发者额外添加任何属性。
因此,一个容易记住的要点是:看到header不要只想到“页面顶部那条”,应该先问自己“这段内容在哪个区块里”,然后再决定是否使用header。很多人把全站页头理解为“唯一的header”,导致在写文章头部时又套了一个<div class="article-header">来手工模拟语义,这其实是语义化不彻底的表现。
header标签内容的取舍与常见错误写法
另一个高频问题是:header里到底能放什么东西?规范文档里列举了几类适合放在header中的内容:标题类元素(h1到h6中至少一个)、导航导航类元素、Logo图片、搜索表单、作者相关信息、出版物相关信息等。要点是,header应该以“引导性”内容为主,那些不属于区块核心介绍的辅助信息(比如版权声明、联系方式、法律条款等),应该放在footer或区块末端的<address>中。
比较常见的错误写法有以下几种。第一种是在header里塞入过多的导航链接,甚至把页脚的内容复制到头部;第二种是把整个页面的所有内容都包裹进header,使得header退化成无意义的div;第三种是页面里没有任何标题元素,header里只有一张Logo图片和搜索框。第三种写法虽然不违反规范,但从语义化角度看,缺少标题元素会让页头的语义大打折扣。准确的做法是:如果页面需要清晰的文档大纲,页头至少应该包含一个<h1>或<h2>作为站点名称或页面主标题。
在页面级页头中,Logo和<h1>并存的情况非常常见。有的团队选择用<h1>包裹Logo文字,有的则让Logo作为纯图片再配一个隐藏的<h1>,这些做法在语义上都是可行的。核心原则是:让<h1>成为整个页面大纲中的第一个节点,然后把这个节点放在页面页头的<header>中。下面这两段代码对比了错误与推荐写法:
<!-- 错误的写法:header中堆砌过多非引导性内容 -->
<header>
<div class="top-bar">
<span>公司地址:某某路100号</span>
<span>客服电话:400-000-0000</span>
<span>招聘信息</span>
<span>友情链接</span>
</div>
<img src="logo.png" alt="Logo" />
<nav>...</nav>
<div class="banner">大横幅广告</div>
<div class="stock-info">股票行情展示</div>
</header>
<!-- 推荐的写法:header内容精简且有层级 -->
<header>
<a href="/" class="logo">
<img src="logo.png" alt="某某科技官网" />
</a>
<h1 class="visually-hidden">某某科技</h1>
<nav>
<ul>
<li><a href="/products">产品</a></li>
<li><a href="/support">支持</a></li>
</ul>
</nav>
<form role="search" action="/search">
<input type="search" name="keyword" placeholder="搜索" />
<button type="submit">搜索</button>
</form>
</header>
看到区别了吗?错误的写法中,header成了一个大杂烩容器,连股票行情这种和页头引导毫无关系的信息都被塞了进来,搜索引擎抓取时很难判断哪些内容重要;推荐的写法中,header只保留了Logo、主标题、导航和搜索功能,都是真正属于“页头介绍性区域”的信息。另外还要特别注意,<header>标签内部不能直接嵌套另一个<header>,也不能放置<footer>标签,这些嵌套限制是写代码时需要规避的。
对于页面标题的处理,很多站点采用“一个<h1>只出现一次”的规则。但在HTML5的文档大纲算法中,每个section都可以有自己的标题层级,所以文章内部的头部使用<h2>、侧边栏模块的头部使用<h3>都是正常的。记住一个规律:全站页头中的数据,通常用<h1>或<h2>;区块头部中的数据,根据嵌套深度使用对应的标题级别,保持大纲结构不要跳级。
header标签的自动化语义与可访问性收益
在可访问性方面,<header>标签有一个容易被忽视的好处:当它作为body的直接子元素时,会被浏览器和辅助工具自动识别为banner(横幅区域)地标;当它嵌套在<article>、<section>等区块内时,则不会被识别为banner,而是普通的分区头部。这种根据上下文自动变换语义的能力,是使用<div id="header">时完全没有的。
什么叫banner地标?屏幕阅读器用户可以通过地标(landmark)快速跳转到页面的主要区域。如果页面顶部用了<div>,辅助技术无法判断它的作用;如果用<header>且位于body下一级,辅助技术会自动把它标记为banner,用户可以用快捷键一键跳转到页头。同时,<header>会参与文档大纲的构建,有利于浏览器扩展和SEO工具分析页面结构。这也是为什么规范推荐页面级页头使用header,而不是用<div + role="banner">来手工模拟。
接下来看一个比较完整的综合示例,它展示了页面级页头配合区块头部的完整写法。同时,这个示例也用了<hgroup>标签来处理主标题与副标题并列的场景。hgroup在HTML5规范草案中曾被移除,后来在HTML 5.1中重新回归,它用来把一组标题封装为一个整体,避免副标题中的<p>干扰文档大纲的层级:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>某某科技 - 产品中心</title>
</head>
<body>
<header>
<hgroup>
<h1>某某科技</h1>
<p>专注企业级云服务</p>
</hgroup>
<nav aria-label="主导航">
<ul>
<li><a href="/">首页</a></li>
<li><a href="/products" aria-current="page">产品</a></li>
<li><a href="/about">关于我们</a></li>
</ul>
</nav>
</header>
<main>
<article>
<header>
<h2>云主机产品介绍</h2>
<p>更新时间:2024年3月 </p>
</header>
<p>云主机是基于KVM架构的弹性计算服务……</p>
</article>
<section aria-labelledby="news-title">
<header>
<h2 id="news-title">最新动态</h2>
</header>
<ul>
<li><a href="/news/1">某某科技获B轮融资</a></li>
<li><a href="/news/2">新一代云平台上线</a></li>
</ul>
</section>
</main>
<footer>
<p>© 2024 某某科技 保留所有权利</p>
</footer>
</body>
</html>
最后再补充一个关于SEO的实践观察。搜索引擎在提取页面摘要和判断页面主内容时,会比较看重header区域中标题标签的权重。如果一个页面的页头正确地使用了<header>并包含了唯一的<h1>,搜索引擎对页面的主题判定通常更准确;反之,如果页面只有大量嵌套的<div>,每个区块的标题层级混乱,搜索引擎就需要花费更多算力去推断主题。因此,做好header的语义化并不只是为了“较真规范”,它对真实的搜索流量和用户体验都能产生实质帮助。
写页头时,可以在心里过一遍这三个问题:header里是否只包含引导性内容?是否至少有一个明确的标题元素?位置是否在对应区块的最前面?如果三个问题的答案都是肯定的,那么这个header的用法就是基本正确的。语义化没有绝对的唯一解,关键是在写每一行HTML时,都能理解标签背后的语义上下文,这样写出来的页面才能既符合规范、又对用户和搜索引擎友好。