语义标签是内容角色声明而非视觉分块:<main>表示用户真正想看的唯一主体内容,必须为<body>直系子元素;<section>须有标题才具语义;无明确角色时应回退<div>。

语义标签不是“视觉分块”,而是“内容角色声明”
很多人一看到 <section> 就想套个边框,看到 <aside> 就默认往右摆,这是把语义当成了 CSS 布局指令。实际上,这些标签回答的唯一问题是:“这段内容在整页信息结构里扮演什么角色?”
-
<main>表示“用户点进来真正想看的东西”,不是“中间那块区域” -
<nav>表示“一组用于跳转到其他资源的链接”,不是“顶部横条菜单” -
<article>表示“能独立存在、可被 RSS 抓取或转发的完整内容单元”,比如一篇博客、一条新闻、一个评论——它不取决于有没有标题,而取决于能否脱离当前页面仍成立 -
<section>是“有共同主题的一组内容”,必须带<h1>–<h6>才算有效语义;没标题的<section>对屏幕阅读器和爬虫等于不存在
<main> 必须是 <body> 的直系子元素,否则语义坍塌
常见错误是把 <main> 包在 <div class="wrapper"> 里,或者嵌在 <header> 下面。浏览器和辅助技术会直接忽略它的“主内容”身份,因为规范强制要求它代表整页唯一入口。
- 合法结构:
<body><header>...</header><main>...</main><footer>...</footer></body></li> <li>非法结构:<code><body><div class="container"><main>...</main></div></body>
(除非该<div>完全透明:无aria-hidden、无display: none、无语义污染) - 更隐蔽的坑:
<main>父级加了aria-hidden="true"或inert,内容瞬间对屏幕阅读器不可见
<time datetime> 不写 datetime 属性就等于没用
<time>2025-06-05</time> 在 HTML 中只是四个普通字符;只有加上 datetime,才具备机器可读的时间语义。
- 正确写法:
<time datetime="2025-06-05T14:30">今天下午2:30</time> - 错误写法:
<time>今天下午2:30</time>(无datetime,屏幕阅读器读作“今 天 下 午 2 : 3 0”,日历应用无法识别) - 格式必须严格:支持
YYYY-MM-DD、YYYY-MM-DDThh:mm、hh:mm,不接受中文日期、模糊表述(如“上周三”)
什么时候该退回 <div>?
不是所有容器都需要语义。硬套反而制造噪音。
立即学习“前端免费学习笔记(深入)”;
- 纯布局容器:CSS Grid / Flex 的外层包裹盒,若仅用于对齐、间距、响应式断点,用
<div class="grid-container">更干净 - 动态组件输出:React/Vue 组件返回值中,若语义层级在运行时不确定(比如卡片组件可能渲染为
<article>或<section>),优先用<div role="region" aria-labelledby="xxx"> - 软件界面控件:仪表盘中的实时数据卡片、表单操作区、状态切换面板——它们本质是交互载体,不是内容单元,
<div>+ ARIA 比强行塞进<article>更准确



















