Skip to content

main 主体内容

<main> 元素表示文档的主体内容区域。每个页面应该只有一个 <main> 元素,它包含了页面的核心内容,排除导航栏、侧边栏、页脚、Logo 等非主要内容。它是无障碍访问中最重要的 landmark 之一。

前置知识

阅读本节前,建议先了解:nav 导航

基础概念

什么是 main

<main> 是 HTML5 引入的语义化标签,用于包裹页面的主要内容。它的核心特征是唯一性——一个文档中只能有一个 <main> 元素。

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>main 示例</title>
</head>
<body>
  <header>...</header>
  <!-- 主内容区域:整个页面唯一 -->
  <main>
    <h1>页面标题</h1>
    <p>这是页面的主要内容...</p>
  </main>
  <footer>...</footer>
</body>
</html>

main 的核心特征

特征说明
唯一性每个页面只能有一个 <main> 元素
隐式角色自动映射为 ARIA main 角色
Landmark屏幕阅读器识别为 "main" landmark,支持快捷键跳转
内容排除不包含 header、footer、nav、aside 等重复性内容
可聚焦可通过 id 属性作为 skip-to-content 的目标

语法与使用

基本语法

html
<!-- 基本用法 -->
<main>
  <!-- 页面的核心内容 -->
</main>

<!-- 带有 id(用于 skip-to-content) -->
<main id="main-content">
  <!-- 页面的核心内容 -->
</main>

main 的位置

<main> 通常位于 <body> 的直接子元素中,在 <header> 之后、<footer> 之前:

html
<body>
  <header>...</header>
  <nav>...</nav>
  <main>...</main>
  <aside>...</aside>
  <footer>...</footer>
</body>

main 可以包含的内容

<main> 内部可以包含任何流内容,通常包括:

  • <article> —— 独立文章
  • <section> —— 内容章节
  • <aside> —— 与主内容相关的辅助信息
  • <h1>-<h6> —— 标题
  • <figure> —— 图表
  • <p><ul><ol><table> 等常规内容

详细说明

Skip-to-Content 跳转链接

<main> 最常见的无障碍应用是作为"跳转到主内容"链接的目标:

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Skip-to-Content 示例</title>
  <style>
    /* Skip link:默认隐藏,Tab 聚焦时显示 */
    .skip-link {
      position: absolute;
      top: -100%;
      left: 0;
      background: #0078d7;
      color: #fff;
      padding: 0.75rem 1.5rem;
      z-index: 10000;
      text-decoration: none;
      border-radius: 0 0 4px 0;
      transition: top 0.2s ease;
    }
    .skip-link:focus {
      top: 0;
      outline: 2px solid #fff;
    }

    body {
      margin: 0;
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
      line-height: 1.6;
    }

    .site-header {
      background: #1a1a2e;
      color: #fff;
      padding: 1rem 2rem;
      display: flex;
      justify-content: space-between;
    }

    .site-nav ul {
      list-style: none;
      display: flex;
      gap: 1rem;
      margin: 0;
      padding: 0;
    }

    .site-nav a {
      color: #e0e0e0;
      text-decoration: none;
      padding: 0.5rem 1rem;
    }

    main {
      max-width: 800px;
      margin: 2rem auto;
      padding: 0 2rem;
    }

    .site-footer {
      background: #1a1a2e;
      color: #999;
      text-align: center;
      padding: 1rem;
      margin-top: 2rem;
    }
  </style>
</head>
<body>
  <a class="skip-link" href="#main-content">跳转到主要内容</a>

  <header class="site-header">
    <h1>我的网站</h1>
    <nav class="site-nav" aria-label="主导航">
      <ul>
        <li><a href="/">首页</a></li>
        <li><a href="/about">关于</a></li>
        <li><a href="/blog">博客</a></li>
      </ul>
    </nav>
  </header>

  <main id="main-content">
    <h1>欢迎来到我的网站</h1>
    <p>这是页面的主要内容区域。键盘用户可以通过 Tab 键聚焦到
    "跳转到主要内容" 链接,然后按 Enter 直接跳过导航栏到达这里。</p>

    <section>
      <h2>最新文章</h2>
      <article>
        <h3>HTML5 语义化标签</h3>
        <p>语义化标签让网页结构更清晰...</p>
      </article>
      <article>
        <h3>CSS Grid 布局</h3>
        <p>CSS Grid 是二维布局系统...</p>
      </article>
    </section>
  </main>

  <footer class="site-footer">
    <p>&copy; 2024 我的网站. 保留所有权利.</p>
  </footer>
</body>
</html>

main 的排除内容规则

<main> 不应包含以下内容:

排除内容原因
站点级 header/footer在多个页面重复出现,不属于"主体"
站点级导航导航是辅助功能,不是页面主要内容
侧边栏广告与主内容无直接关系的辅助内容
全局搜索框全局搜索不属于特定页面的内容
html
<!-- 错误:main 内包含重复性内容 -->
<main>
  <header>
    <h1>网站名称</h1>
    <nav>全局导航</nav>
  </header>
  <h1>文章标题</h1>
  <p>文章内容...</p>
  <footer>版权所有</footer>
</main>

<!-- 正确:main 只包含页面特有的内容 -->
<body>
  <header>
    <h1>网站名称</h1>
    <nav>全局导航</nav>
  </header>
  <main>
    <article>
      <header>
        <h1>文章标题</h1>
      </header>
      <p>文章内容...</p>
      <footer>文章标签</footer>
    </article>
  </main>
  <footer>版权所有</footer>
</body>

<main> 内可以包含文章级别的 <header><footer>,因为它们属于内容本身的一部分:

html
<main>
  <article>
    <header>
      <h2>文章标题</h2>
      <time datetime="2024-01-15">2024 年 1 月 15 日</time>
    </header>
    <p>正文内容...</p>
    <footer>
      <p>作者:张三</p>
    </footer>
  </article>
</main>

实战示例

博客文章页面的 main

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>博客文章 - main 示例</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { font-family: -apple-system, sans-serif; color: #333; }

    .skip-link {
      position: absolute; top: -100%; left: 0;
      background: #0078d7; color: #fff;
      padding: 0.5rem 1rem; z-index: 10000; text-decoration: none;
    }
    .skip-link:focus { top: 0; }

    .page-header {
      background: #2c3e50; color: #ecf0f1; padding: 1rem 2rem;
    }
    .page-header-inner {
      max-width: 1000px; margin: 0 auto;
      display: flex; justify-content: space-between; align-items: center;
    }
    .page-header nav a {
      color: #bdc3c7; text-decoration: none; margin-left: 1.5rem;
    }
    .page-header nav a:hover { color: #fff; }

    .page-body {
      max-width: 1000px; margin: 2rem auto; padding: 0 2rem;
      display: grid; grid-template-columns: 1fr 300px; gap: 2rem;
    }

    main article {
      background: #fff; padding: 2rem;
      border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1);
    }
    main article header {
      margin-bottom: 1.5rem; border-bottom: 1px solid #eee; padding-bottom: 1rem;
    }
    main article header h1 { font-size: 1.75rem; margin-bottom: 0.5rem; }
    .article-meta { color: #7f8c8d; font-size: 0.875rem; }

    main section { margin: 2rem 0; }
    main section h2 { color: #2c3e50; margin-bottom: 1rem; }

    main article footer {
      margin-top: 2rem; padding-top: 1rem;
      border-top: 1px solid #eee; color: #95a5a6; font-size: 0.9rem;
    }

    /* 侧边栏不在 main 内 */
    .sidebar { display: flex; flex-direction: column; gap: 1.5rem; }
    .sidebar-widget {
      background: #f8f9fa; padding: 1.25rem; border-radius: 8px;
    }
    .sidebar-widget h3 { font-size: 1rem; margin-bottom: 0.75rem; color: #2c3e50; }
    .sidebar-widget ul { list-style: none; }
    .sidebar-widget li { margin-bottom: 0.5rem; }
    .sidebar-widget a { color: #3498db; text-decoration: none; font-size: 0.9rem; }

    .page-footer {
      background: #2c3e50; color: #95a5a6;
      text-align: center; padding: 1rem; margin-top: 2rem;
    }
  </style>
</head>
<body>
  <a class="skip-link" href="#main-content">跳转到主要内容</a>

  <header class="page-header">
    <div class="page-header-inner">
      <h1>TechBlog</h1>
      <nav aria-label="主导航">
        <a href="/">首页</a>
        <a href="/articles">文章</a>
        <a href="/about">关于</a>
      </nav>
    </div>
  </header>

  <div class="page-body">
    <main id="main-content">
      <article>
        <header>
          <h1>深入理解 CSS Grid 布局</h1>
          <p class="article-meta">
            作者:<address><a href="/author/zhangsan" style="color:#3498db">张三</a></address>
            &middot; <time datetime="2024-01-15">2024 年 1 月 15 日</time>
            &middot; 阅读时间:10 分钟
          </p>
        </header>

        <section>
          <h2>什么是 CSS Grid</h2>
          <p>CSS Grid 布局是 CSS 中最强大的布局系统之一。它是一个二维系统,可以同时处理列和行。</p>
        </section>

        <section>
          <h2>基础用法</h2>
          <p>要使用 Grid 布局,首先需要创建一个网格容器...</p>
        </section>

        <footer>
          <p>标签:CSS、布局、Grid、前端</p>
        </footer>
      </article>
    </main>

    <aside class="sidebar">
      <div class="sidebar-widget">
        <h3>相关文章</h3>
        <ul>
          <li><a href="#">Flexbox 完全指南</a></li>
          <li><a href="#">CSS 定位详解</a></li>
          <li><a href="#">响应式设计实践</a></li>
        </ul>
      </div>
    </aside>
  </div>

  <footer class="page-footer">
    <p>&copy; 2024 TechBlog. All rights reserved.</p>
  </footer>
</body>
</html>

注意事项

常见错误

  1. 页面中有多个 main:违反规范,每个文档只能有一个 <main>
html
<!-- 错误:多个 main -->
<main><h1>第一部分</h1></main>
<main><h1>第二部分</h1></main> <!-- 错误! -->

<!-- 正确:使用 section 划分 -->
<main>
  <section><h1>第一部分</h1></section>
  <section><h1>第二部分</h1></section>
</main>
  1. main 内包含全局导航:站点级导航不应出现在 <main>
  2. 缺少 main 标签:每个页面都应该有一个 <main> 来标识主内容区域

main 与 role="main"

html
<!-- 不需要手动添加 role,浏览器会自动处理 -->
<main role="main"> <!-- 冗余 -->
  ...
</main>

<!-- 正确写法 -->
<main>
  ...
</main>

最佳实践

  1. 始终使用 main 包裹主要内容:即使页面很简单,也应该使用 <main>
  2. 添加 id 用于 skip link<main id="main-content"> 作为跳转目标
  3. 配合 skip-link 使用:为键盘用户提供快速跳过导航的途径
  4. 不要在 main 内放置重复内容:全局 header、footer、nav 应该在 main 之外
  5. SPA 中动态更新 main:在单页应用中,只更新 <main> 内的内容

下一节

继续学习:article 文章

参考链接