header 页眉
<header> 元素表示页面或内容区块的头部区域,通常包含标题、导航、Logo、搜索框等引导性内容。它是一个语义化容器,用于将页眉相关的内容进行逻辑分组。
前置知识
阅读本节前,建议先了解:语义化概述
基础概念
什么是 header
<header> 是 HTML5 引入的语义化标签,用于表示介绍性内容或导航辅助内容的容器。它可以出现在两个层级:
- 页面级
<header>:作为整个页面的头部,通常包含网站 Logo、站点名称、全局导航 - 章节级
<header>:作为<article>、<section>、<aside>等内容的头部,包含该区块的标题和元信息
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>header 示例</title>
</head>
<body>
<!-- 页面级 header:整个网站的头部 -->
<header>
<img src="/logo.svg" alt="网站 Logo">
<nav>...</nav>
</header>
<!-- 章节级 header:文章的头部 -->
<main>
<article>
<header>
<h1>文章标题</h1>
<p>作者信息、发布时间</p>
</header>
<p>正文内容...</p>
</article>
</main>
</body>
</html>header 的隐式角色
<header> 的 ARIA 角色取决于它在文档中的位置:
| 位置 | 隐式 ARIA 角色 | 说明 |
|---|---|---|
<body> 的直接子元素 | banner | 页面级横幅 |
<article> 内 | 无特定角色 | 文章头部 |
<section> 内 | 无特定角色 | 章节头部 |
<aside> 内 | 无特定角色 | 侧边栏头部 |
注意:当
<header>不是<body>的直接子元素时,它不会被识别为 landmark,屏幕阅读器不会为其提供特殊的导航快捷键。
语法与使用
基本语法
html
<header>
<!-- 可以包含任何流内容 -->
<h1>标题</h1>
<p>描述文字</p>
<nav>导航链接</nav>
</header>header 可以包含的内容
<header> 可以包含以下类型的内容:
| 内容类型 | 说明 | 示例 |
|---|---|---|
| 标题元素 | h1-h6 | <h1>网站名称</h1> |
| 导航 | nav 元素 | <nav>...</nav> |
| Logo/图片 | img 元素 | <img src="logo.svg" alt="Logo"> |
| 搜索框 | search/form 元素 | <search>...</search> |
| 段落文字 | 介绍性文字 | <p>副标题或描述</p> |
| 联系信息 | address 元素 | <address>作者信息</address> |
| 时间信息 | time 元素 | <time>发布日期</time> |
| 操作按钮 | 按钮组 | <button>登录</button> |
header 的出现规则
<header> 在 HTML 规范中有明确的出现规则:
- 一个页面可以有多个
<header>(页面级 + 章节级) - 不能在
<header>、<footer>、<address>内嵌套<header> - 不要求每个区块都有
<header>,只有当区块确实有头部内容时才使用
html
<!-- 正确:页面级和章节级 header -->
<body>
<header>
<h1>网站名称</h1>
</header>
<main>
<article>
<header>
<h2>文章标题</h2>
</header>
<p>正文...</p>
</article>
</main>
</body>
<!-- 错误:header 不能嵌套在另一个 header 中 -->
<header>
<header> <!-- 这是错误的 -->
<h1>标题</h1>
</header>
</header>
<!-- 错误:header 不能嵌套在 footer 中 -->
<footer>
<header> <!-- 这是错误的 -->
<h2>链接</h2>
</header>
</footer>详细说明
页面级 header
页面级 <header> 是网站的全局头部区域,通常出现在 <body> 的最前面:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>页面级 header 示例</title>
<style>
/* 页面级 header 样式 */
.site-header {
background: #1a1a2e;
color: #fff;
padding: 1rem 2rem;
display: flex;
align-items: center;
justify-content: space-between;
position: sticky;
top: 0;
z-index: 100;
}
.site-logo {
display: flex;
align-items: center;
gap: 0.75rem;
}
.site-logo img {
width: 40px;
height: 40px;
}
.site-logo h1 {
margin: 0;
font-size: 1.25rem;
}
.site-nav ul {
list-style: none;
display: flex;
gap: 1.5rem;
margin: 0;
padding: 0;
}
.site-nav a {
color: #e0e0e0;
text-decoration: none;
font-size: 0.9rem;
transition: color 0.2s;
}
.site-nav a:hover {
color: #fff;
}
.header-actions {
display: flex;
align-items: center;
gap: 1rem;
}
.header-search {
padding: 0.4rem 1rem;
border: 1px solid rgba(255,255,255,0.3);
border-radius: 20px;
background: rgba(255,255,255,0.1);
color: #fff;
outline: none;
}
.header-search::placeholder {
color: rgba(255,255,255,0.5);
}
</style>
</head>
<body>
<!-- 页面级 header -->
<header class="site-header">
<!-- Logo 和站点名称 -->
<div class="site-logo">
<img src="/logo.svg" alt="网站 Logo" width="40" height="40">
<h1>我的网站</h1>
</div>
<!-- 全局导航 -->
<nav class="site-nav" aria-label="主导航">
<ul>
<li><a href="/">首页</a></li>
<li><a href="/products">产品</a></li>
<li><a href="/blog">博客</a></li>
<li><a href="/about">关于</a></li>
</ul>
</nav>
<!-- 操作区域 -->
<div class="header-actions">
<input type="search" class="header-search" placeholder="搜索..." aria-label="搜索">
<button>登录</button>
</div>
</header>
<main>
<p>页面内容...</p>
</main>
</body>
</html>章节级 header
章节级 <header> 用于为 <article>、<section> 等区块提供头部信息:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>章节级 header 示例</title>
<style>
/* 文章列表页样式 */
.article-list {
max-width: 800px;
margin: 2rem auto;
padding: 0 1rem;
}
.article-item {
border-bottom: 1px solid #eee;
padding-bottom: 1.5rem;
margin-bottom: 1.5rem;
}
.article-item header {
margin-bottom: 0.75rem;
}
.article-item h2 {
margin: 0 0 0.25rem;
}
.article-meta {
color: #666;
font-size: 0.875rem;
margin: 0;
}
.article-item p {
color: #444;
line-height: 1.6;
}
</style>
</head>
<body>
<header>
<h1>技术博客</h1>
<nav aria-label="主导航">
<a href="/">首页</a> |
<a href="/archive">归档</a>
</nav>
</header>
<main class="article-list">
<!-- 每篇文章都有自己的 header -->
<article class="article-item">
<header>
<h2><a href="/post-1">深入理解 CSS Grid 布局</a></h2>
<p class="article-meta">
<address>作者:<a href="/author/zhangsan">张三</a></address>
·
<time datetime="2024-01-10">2024 年 1 月 10 日</time>
·
阅读时间:8 分钟
</p>
</header>
<p>CSS Grid 是二维布局系统,可以同时控制行和列...</p>
</article>
<article class="article-item">
<header>
<h2><a href="/post-2">JavaScript 异步编程完全指南</a></h2>
<p class="article-meta">
<address>作者:<a href="/author/lisi">李四</a></address>
·
<time datetime="2024-01-08">2024 年 1 月 8 日</time>
·
阅读时间:12 分钟
</p>
</header>
<p>从回调函数到 Promise 再到 async/await...</p>
</article>
</main>
</body>
</html>多个 header 的场景
一个页面可以有多个 <header>,每个服务于不同的上下文:
html
<body>
<!-- 页面级 header -->
<header>
<h1>网站名称</h1>
<nav aria-label="全局导航">...</nav>
</header>
<main>
<!-- 文章的 header -->
<article>
<header>
<h2>文章标题</h2>
<p>发布信息...</p>
</header>
<p>正文...</p>
<!-- 文章内章节的 header -->
<section>
<header>
<h3>第一节:引言</h3>
</header>
<p>引言内容...</p>
</section>
</article>
<!-- 侧边栏的 header -->
<aside>
<header>
<h2>相关文章</h2>
</header>
<ul>
<li><a href="#">相关文章1</a></li>
</ul>
</aside>
</main>
</body>实战示例
响应式页面 header
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>响应式 header 示例</title>
<style>
/* 重置样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
/* 页面 header */
.site-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: #fff;
padding: 0 2rem;
}
.header-top {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem 0;
}
/* Logo 区域 */
.logo {
display: flex;
align-items: center;
gap: 0.5rem;
text-decoration: none;
color: #fff;
}
.logo-icon {
width: 36px;
height: 36px;
background: rgba(255,255,255,0.2);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-size: 1.2rem;
}
.logo-text {
font-size: 1.25rem;
font-weight: 600;
}
/* 导航 */
.main-nav {
display: flex;
align-items: center;
gap: 0.25rem;
}
.main-nav a {
color: rgba(255,255,255,0.85);
text-decoration: none;
padding: 0.5rem 1rem;
border-radius: 6px;
font-size: 0.9rem;
transition: all 0.2s;
}
.main-nav a:hover {
color: #fff;
background: rgba(255,255,255,0.15);
}
.main-nav a.active {
color: #fff;
background: rgba(255,255,255,0.2);
}
/* 用户操作区 */
.user-actions {
display: flex;
align-items: center;
gap: 0.75rem;
}
.btn {
padding: 0.5rem 1.25rem;
border-radius: 6px;
border: none;
cursor: pointer;
font-size: 0.9rem;
transition: all 0.2s;
}
.btn-outline {
background: transparent;
color: #fff;
border: 1px solid rgba(255,255,255,0.4);
}
.btn-outline:hover {
background: rgba(255,255,255,0.1);
}
.btn-primary {
background: #fff;
color: #667eea;
font-weight: 600;
}
.btn-primary:hover {
background: #f0f0f0;
}
/* 移动端菜单按钮 */
.menu-toggle {
display: none;
background: none;
border: none;
color: #fff;
font-size: 1.5rem;
cursor: pointer;
padding: 0.25rem;
}
/* 响应式:移动端 */
@media (max-width: 768px) {
.main-nav, .user-actions {
display: none;
}
.menu-toggle {
display: block;
}
}
</style>
</head>
<body>
<!-- 响应式页面 header -->
<header class="site-header">
<div class="header-top">
<!-- Logo -->
<a href="/" class="logo">
<span class="logo-icon">H</span>
<span class="logo-text">HtmlLearn</span>
</a>
<!-- 主导航 -->
<nav class="main-nav" aria-label="主导航">
<a href="/" class="active">首页</a>
<a href="/tutorials">教程</a>
<a href="/examples">示例</a>
<a href="/reference">参考</a>
<a href="/community">社区</a>
</nav>
<!-- 用户操作 -->
<div class="user-actions">
<button class="btn btn-outline">登录</button>
<button class="btn btn-primary">注册</button>
</div>
<!-- 移动端菜单按钮 -->
<button class="menu-toggle" aria-label="打开菜单">☰</button>
</div>
</header>
<main>
<p>页面主内容区域...</p>
</main>
</body>
</html>注意事项
常见错误
- 过度使用 header:不是每个区块都需要 header,只在确实有头部内容时使用
html
<!-- 不推荐:没有头部内容的区块不需要 header -->
<section>
<header></header> <!-- 空 header 没有意义 -->
<p>内容...</p>
</section>
<!-- 推荐:只在有头部内容时使用 -->
<section>
<header>
<h2>章节标题</h2>
</header>
<p>内容...</p>
</section>header 内必须有内容:空
<header>是不合理的页面级 header 不需要 role="banner":浏览器会自动识别
html
<!-- 不需要手动添加 role -->
<header role="banner"> <!-- 冗余,浏览器会自动处理 -->
...
</header>
<!-- 正确写法 -->
<header>
...
</header>header 与 div 的选择
| 场景 | 推荐标签 | 原因 |
|---|---|---|
| 网站顶部区域 | <header> | 有明确的页眉语义 |
| 文章标题区域 | <header> | 引导性内容 |
| 纯样式包装容器 | <div> | 无语义含义 |
<article> 内的标题+元数据 | <header> | 标准用法 |
| Flexbox/Grid 布局容器 | <div> | 纯布局目的 |
最佳实践
- 页面级 header 应该简洁:包含 Logo、导航和核心操作即可,不要放入过多内容
- 使用 sticky 固定导航:页面级 header 通常需要固定在顶部
- 添加 aria-label:当页面有多个
<header>时,可以添加标签帮助区分 - 配合 skip-link 使用:为键盘用户提供跳过 header 的快捷方式
- 移动端适配:使用响应式设计处理小屏幕下的 header 布局
下一节
继续学习:nav 导航