页面语义化达标需验证标签与内容真实对应:必须仅有一个和,包裹全部主体内容且不嵌套于或中,内不含搜索框或登录按钮;不可套单个或整页用户列表,须可独立分发,仅作逻辑分组;标题层级须连续无跳级,等细节标签及其属性不可省略。

怎么判断一个页面的语义化是否达标
不能靠“用了几个 <header></header>”来数,得看标签是否与内容真实对应。W3C Validator 只能验语法,不验语义;真正有效的检查点是:页面是否只有一个 <h1></h1>、<main></main> 是否包裹全部主体内容、<nav></nav> 里有没有塞搜索框或登录按钮。
常见错误现象:
-
<section></section>套着单个<button></button>或整页用户列表(每条记录才该是独立<article></article>) -
<main></main>被包在<header></header>或<nav></nav>里 - 用
<div class="h2"> 替代 <code><h2></h2>,只为了样式妥协语义实操建议:
- 打开 Chrome DevTools → 「Accessibility」面板 → 展开「Heading level」,看是否连续无跳级
- 用
axe-core浏览器插件跑一次,重点看 “landmark” 和 “heading-order” 规则失败项 - 服务端渲染时,在构建流程中加
remark-lint-heading-increment检查 Markdown 输出的标题层级
为什么
<article></article>和<section></section>容易混用根本区别不在“能不能嵌套”,而在“能否独立分发”。
<article></article>是自包含的内容单元(比如一篇博客、一条新闻、一个评论),可被 RSS 抓取、被社交平台单独引用;<section></section>只是文档里的一个逻辑区块,必须依附上下文存在。使用场景差异:
- 用户列表页:每个用户卡片用
<article></article>,整个列表容器用<section></section> - 文章正文内多个小节(如“背景”“方法”“结论”):用
<section></section>,每个小节必须带<h2></h2>–<h6></h6> - 侧边栏的“相关文章”:用
<aside></aside>,不是<section></section>,更不是<div> <p>容易踩的坑:</p><div class="aritcle_card flexRow artxards"> <div class="artcardd flexRow"> <a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill7761" title="Article To Html"><img src="https://img.php.cn/upload/skill/000/000/081/179168408018805.jpg" alt="Article To Html" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a rel="nofollow" href="/xiazai/skill7761" title="Article To Html" class="overflowclass">Article To Html</a> <p class="overflowclass">文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。</p> </div> <a rel="nofollow" href="/xiazai/skill7761" title="Article To Html" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div> <ul> <li>把 CMS 输出的整篇长文直接包进一个 <code><section></section>,却不拆出内部小节的<section></section>—— 结构扁平,辅助技术无法跳转 - 给
<article></article>加aria-labelledby却忽略它自带的隐式 role="article",纯属冗余
<nav></nav>和<footer></footer>的嵌套边界在哪<nav></nav>必须是“导航链接集合”,不是所有链接都算。页脚里的“隐私政策”“用户协议”属于导航,但“微信公众号二维码”不是;<footer></footer>可以出现在<article></article>或<section></section>内部,但页面级<footer></footer>不能嵌套在<header></header>或<nav></nav>中。参数/结构影响:
- 多个
<nav></nav>需用aria-label区分,例如:<nav aria-label="主导航"></nav>、<nav aria-label="页脚导航"></nav> -
<footer></footer>在<article></article>内表示该文章的元信息(作者、发布时间),和页面底部的版权信息不冲突 - 把登录入口塞进
<nav></nav>,会导致屏幕阅读器误判为可导航目标,实际点击却无跳转
性能提示:过度使用
<nav></nav>不影响加载速度,但会污染 ARIA 树,拖慢辅助技术遍历效率。alt、label、time 这些“小标签”为什么不能省略
它们不是锦上添花,而是功能开关。
<img>缺alt,在无图模式下就是空白;<input>没<label></label>,语音助手无法读出字段含义;<time datetime="2024-03-10"></time>比纯文本“3月10日”多出机器可解析的时间戳,搜索引擎和日历工具依赖这个。实操细节:
-
alt=""是合法值,用于纯装饰图;空alt属性(alt)或完全省略,都会被屏幕阅读器当作“未知图像”朗读 -
<label></label>必须与<input>通过for或嵌套关联,仅靠视觉对齐无效 -
<time></time>的datetime值必须是机器可解析格式(ISO 8601),<time datetime="3月10日"></time>会被忽略
最容易被忽略的一点:这些属性一旦缺失,问题不会在开发阶段暴露,而是在弱网、高对比度模式、语音交互等真实场景中突然失效——而且无法被自动化测试覆盖到。










