应优先用header、main、aside、section等语义化标签替代div.row/col,结合grid-template-areas命名区域匹配结构,确保DOM表达力与可访问性;ARIA仅作补充,不可替代语义标签。

用语义化HTML标签替代div.row和div.col
Grid布局本身不强制语义,但很多人仍习惯写一堆带row、col类名的div,这会让DOM失去表达力。屏幕阅读器只看到“一个div”,无法判断这是页眉、主内容还是侧边栏。
直接改用HTML5语义标签作为Grid容器或项目:
-
<header></header>替代<div class="row header">,配合 <code>role="banner"明确用途 -
<main></main>必须唯一,且应作为核心内容区域的网格项,不能嵌套在section里当普通容器用 -
<aside></aside>天然对应侧栏列,比<div class="sidebar"> 更可信——即使CSS Grid把它放到顶部,语义仍是“补充信息” <li> <code><section></section>适合做逻辑分组(如“产品列表区”),但别滥用;若内部只有标题+几个article,优先让article直属于main -
grid-area值必须与grid-template-areas中的字符串完全一致,大小写敏感,空格也不能多一个 - 用
.表示空单元格,但别为了“对齐美观”强行补点——它代表真实空白区域,会影响阅读器遍历顺序 - 如果某区块需跨多区域(如全宽横幅),用
grid-area: banner;+grid-template-areas: "banner banner",别拆成两个同名区域再合并 <div role="main"> —— 仅当页面中确实没有<code><main></main>时使用;已有<main></main>再加role="main"属冗余<div role="complementary"> —— 适配<code><aside></aside>语义,尤其当<aside></aside>被CSS Grid移到视觉末尾,但逻辑上仍是补充内容<div role="region" aria-label="搜索筛选区"> —— 对无标准语义的交互模块(如复杂筛选面板)必须提供<code>aria-label,否则屏幕阅读器只会念“region”- 避免
role="application"或role="document":Grid布局本身不构成应用级交互,加了反而干扰阅读器默认行为 - 标题层级是否断裂:比如
<main></main>内第一个标题是<h2></h2>,但前面<header></header>里没<h1></h1>,阅读器会困惑 - 交互控件是否有
tabindex干扰:Grid项目本身不聚焦,但里面按钮/输入框必须保持自然Tab顺序 - 媒体查询切换布局时,DOM是否同步调整:比如小屏把
<aside></aside>移到<main></main>下方,DOM也得真移,不能只靠order或grid-area视觉挪动
用grid-area配合grid-template-areas保持结构可读性
命名区域不是炫技,而是把布局意图写进CSS,让开发者和辅助技术都能对齐理解。比如grid-template-areas: "header header" "sidebar main" "footer footer",比计算grid-column: 2 / 4直观得多。
关键点:
立即学习“前端免费学习笔记(深入)”;
ARIA角色不能替代语义标签,但能补足缺失上下文
有些场景下你无法改HTML结构(比如CMS输出固定div),这时ARIA是最后防线。但注意:role只是“告诉”辅助技术这是什么,不改变DOM本质,也不影响样式或JS选择器。
常用组合:
阅读顺序与DOM顺序不一致时,aria-flowto不是解药
CSS Grid可以任意重排视觉位置,但屏幕阅读器严格按DOM顺序读取。如果你把<aside></aside>写在<main></main>后面,却用Grid把它显示在左侧,用户会先听到主内容,再听侧栏——这反而是合理顺序。强行用aria-flowto跳转,反而打乱自然流。
真正要检查的是:
Grid语义化的复杂点不在代码怎么写,而在于每次调整布局时,都要同步问一句:“这个元素在页面里‘是什么’,而不只是‘在哪里’。”


















