<main>只能出现一次且必须是<body>直接子元素,因其是W3C强制定义的唯一语义锚点,用于屏幕阅读器“M键跳转”和搜索引擎主题提取;嵌套或重复会破坏可访问性、触发Lighthouse报错并干扰SEO。

为什么只能出现一次且必须是body直接子元素
因为浏览器和辅助技术(如屏幕阅读器)把 <main> 当作全页唯一内容锚点。重复或嵌套会直接导致解析逻辑冲突——比如嵌套在 <header> 里,等于告诉工具“导航栏里藏着主内容”,这会让 Lighthouse 报错 Multiple main landmarks,SEO 爬虫也会降权。
常见出错场景:
- 服务端模板中用条件判断漏掉闭合,导致多个
<main>同时输出 - 前端框架(如 React)动态插入时没校验已存在的
<main> - 误把 CMS 渲染的区块包装成
<main>,而页面已有全局<main>
检查方式:DevTools 的 Accessibility 面板会标红提示;CI 流程中可用 html-validate 配置 rule no-duplicate-main 自动拦截。
用写导航或按钮为什么属于CR拒绝级问题
这不是“不够优雅”,而是功能失效。用 <div class="nav"> 替代 <nav>,屏幕阅读器无法识别导航区域,键盘用户 Tab 键跳不过去;用 <div onclick="..."> 模拟按钮,既不支持 Enter/Space 触发,也无法被 focus,更不会出现在辅助技术的交互控件列表里。
立即学习“前端免费学习笔记(深入)”;
真正该做的:
- 主导航一律用
<nav>,且确保内部有可聚焦的语义化链接(<a href> 或带 role="link" 的元素)
- 所有可点击操作优先用
<button>,禁用时加 disabled 属性(不是仅靠 CSS 灰掉)
- 绝对避免在
<p>、<span>、<div> 上写 onclick 或 onkeydown
alt 和 label 缺失不是“体验差”,是功能不可用
<img> 没 alt,图片加载失败时就是空白;<input> 没 <label>,屏幕阅读器读不出字段用途,键盘用户也聚焦不到——这不是“少个提示”,是表单根本不能用。
实操要点:
-
alt="" 仅用于纯装饰图(如背景分隔线),功能性图片必须描述作用或内容,例如 <img src="submit-btn.png" alt="提交表单">
- 表单控件优先用显式关联:
<label for="email">邮箱</label><input id="email">,比隐式包裹 <label>邮箱<input></label> 兼容性更稳
- 自动检查:CI 中跑
axe-core 或 html-validate 的 require-alt-attribute 和 require-label 规则
section 和 article 的区别不是看长度,而是看能否独立分发
一个博客正文、新闻稿、用户评论,自带作者、时间、标题,能被 RSS 抓取、被搜索引擎当独立条目索引——这是 <article>。而“背景介绍”“技术原理”这类依赖上下文、无法脱离当前页面存在的内容块,才是 <section>。
容易踩的坑:
- 把整页商品列表包进一个
<section>,其实每条商品都该是独立 <article>
- 用
<section> 套单个按钮或链接,应改用 <div>
- 过度嵌套:
<section><section><section> 这种结构既无语义价值,又增加 DOM 复杂度
审查时直接问一句:“这块内容去掉其他部分,还能单独存在、被分享或被搜索到吗?”答案决定该用哪个标签。
这不是“不够优雅”,而是功能失效。用 <div class="nav"> 替代 <nav>,屏幕阅读器无法识别导航区域,键盘用户 Tab 键跳不过去;用 <div onclick="..."> 模拟按钮,既不支持 Enter/Space 触发,也无法被 focus,更不会出现在辅助技术的交互控件列表里。
立即学习“前端免费学习笔记(深入)”;
真正该做的:
- 主导航一律用
<nav>,且确保内部有可聚焦的语义化链接(<a href>或带role="link"的元素) - 所有可点击操作优先用
<button>,禁用时加disabled属性(不是仅靠 CSS 灰掉) - 绝对避免在
<p>、<span>、<div>上写onclick或onkeydown
alt 和 label 缺失不是“体验差”,是功能不可用
<img> 没 alt,图片加载失败时就是空白;<input> 没 <label>,屏幕阅读器读不出字段用途,键盘用户也聚焦不到——这不是“少个提示”,是表单根本不能用。
实操要点:
-
alt=""仅用于纯装饰图(如背景分隔线),功能性图片必须描述作用或内容,例如<img src="submit-btn.png" alt="提交表单"> - 表单控件优先用显式关联:
<label for="email">邮箱</label><input id="email">,比隐式包裹<label>邮箱<input></label>兼容性更稳 - 自动检查:CI 中跑
axe-core或html-validate的require-alt-attribute和require-label规则
section 和 article 的区别不是看长度,而是看能否独立分发
一个博客正文、新闻稿、用户评论,自带作者、时间、标题,能被 RSS 抓取、被搜索引擎当独立条目索引——这是 <article>。而“背景介绍”“技术原理”这类依赖上下文、无法脱离当前页面存在的内容块,才是 <section>。
容易踩的坑:
- 把整页商品列表包进一个
<section>,其实每条商品都该是独立<article> - 用
<section>套单个按钮或链接,应改用<div> - 过度嵌套:
<section><section><section>这种结构既无语义价值,又增加 DOM 复杂度
审查时直接问一句:“这块内容去掉其他部分,还能单独存在、被分享或被搜索到吗?”答案决定该用哪个标签。



















