main必须是body的直接子元素,否则电子政务系统在国标gb/t 39576—2020等合规检测中判定为结构失效;因其语义依赖原生landmark解析,一旦被header、section等包裹,读屏软件跳过、检测工具报错“main landmark not found”,且pdf导出丢失主内容标识。

<main></main> 必须是 的直接子元素,否则电子政务系统在合规性检测(如国标 GB/T 39576—2020、信创环境无障碍测评)中会判定为结构失效。
为什么 <main></main> 被包裹就等于“不存在”
电子政务文档的语义建模依赖浏览器原生 landmark 解析,而非 CSS 类名或 JS 注入。一旦 <main></main> 套在 <div class="container"> 或 <code><section></section> 里,NVDA、Windows Narrator 等国产适配型读屏软件将跳过该节点;Lighthouse 和中国信通院《政务网站无障碍检测工具》均报 “Main landmark not found” 错误。
常见错误现象:
- 页面通过了 W3C HTML 验证,但信创终端(统信 UOS + 永中 Office 浏览插件)无法定位主内容区
- 国家政务服务平台接口返回的 DOM 结构中,
<main></main>节点被标记为role="region"而非role="main" - PDF 导出(基于 Puppeteer + Chromium)丢失语义层级,
<main></main>内容降级为普通段落流
<main></main> 在政务文档中的唯一合法位置
不是“建议放在这里”,而是规范强制要求:它必须紧接在 <header></header> 之后、<footer></footer> 之前,且中间不能插入任何容器类标签。
正确结构只有一种:
… <header></header><main></main><footer></footer>
容易踩的坑:
- 用
flex或grid布局时,为居中加了一层<div class="wrapper"> —— 这层就是语义断点 <li>SSR 框架(如 Nuxt、Umi)自动生成的 layout wrapper 组件默认包裹全部内容,需手动剥离 <code><main></main> - CMS 输出模板中,
<main>{{ content }}</main>被套进<article></article>或<section></section>—— 即使带<h1></h1>也无效 -
<main></main>:承载整份公文/通知/政策解读的主体内容区块(每个页面仅一个) -
<article></article>:用于可独立分发的子项,如“附件1:实施细则”、“政策问答第3条” -
<section></section>:必须含<h2></h2>–<h6></h6>标题,例如“一、适用范围”、“二、申报条件” -
<section class="policy-card"></section>—— 卡片是样式概念,无主题分组逻辑,该用<div> <li> <code><article><p>本通知自发布之日起施行</p></article>—— 缺少标题,语义等价于<div> <li>把整份红头文件正文塞进一个 <code><section></section>—— 它应由多个带编号标题的<section></section>组成,外层用<main></main>
与 <article></article>、<section></section> 的边界怎么划
政务文档中,<main></main> 是容器,<article></article> 是内容单元;二者不互斥,但不可替代。
使用场景:
反例:
最易被忽略的一点:政务系统常做“多端一致性”处理,比如 H5 页面和 PDF 导出共用同一套 DOM 结构。只要 <main></main> 不是 直接子元素,PDF 生成器(如 WeasyPrint、Puppeteer)就无法识别其语义权重,导致导出后失去“主内容”标识 —— 这在审计留痕和电子归档环节会触发合规风险。











