Grid容器不控制Tab键顺序,焦点顺序由DOM结构和tabindex决定;:focus-visible用于键盘聚焦高亮,需配合可聚焦元素及outline-offset适配gap;语义化标签和DOM逻辑顺序是无障碍关键。

Grid容器本身不控制Tab键顺序,必须靠HTML结构和:focus-visible
CSS Grid只是定位工具,它不会自动改变元素的键盘导航顺序。焦点顺序完全由DOM顺序和tabindex决定,Grid仅负责视觉排布。如果你把div用grid-area扔到右上角,但HTML里它在第一个位置,Tab时它仍是第一个获得焦点的元素。
真正起作用的是:focus-visible伪类——它只在用户通过键盘触发焦点时生效,避免鼠标点击时也高亮干扰体验:
.grid-item:focus-visible {
outline: 2px solid #4d90fe;
outline-offset: 2px;
}
- 别用
:focus,否则鼠标点击也会触发,破坏视觉一致性 - 确保所有可交互的Grid子项(如
button、a、带tabindex的div)都声明了:focus-visible - 若需兼容老浏览器,可用
@supports selector(:focus-visible)做渐进增强
Grid项目跨越多轨道时,:focus-visible仍有效,但需注意可聚焦性
当某个Grid项使用grid-column: 1 / -1横跨整行,或grid-row: span 2占两行,它的焦点样式依然正常工作——前提是它本身是可聚焦元素。
常见错误是把div当按钮用却没加tabindex="0":
<div class="card" role="button" tabindex="0">内容</div>
- 纯
div默认不可聚焦,即使它在Grid中位置显眼,Tab也无法停驻 - 若用
role="button",必须配tabindex="0",且监听Enter/Space事件 - 用
button或a语义化标签更稳妥,它们原生支持焦点与键盘交互
网格间隙(gap)影响焦点轮廓显示,需手动调整outline-offset
Grid的gap会在项目间留白,但outline默认从元素边缘向外画,容易被相邻项目的gap“切掉”一部分,导致高亮不完整。
解决方法是用outline-offset把轮廓往外推:
.grid-item:focus-visible {
outline: 2px solid #34a853;
outline-offset: 4px; /* 至少等于gap值 */
}
- 如果
gap: 12px,outline-offset设为4px~6px通常足够,太大则轮廓飘离元素 - 避免用
box-shadow替代outline,它不被屏幕阅读器识别,也不符合无障碍焦点指示规范 - 移动端虚拟键盘弹出时,部分iOS Safari会忽略
outline,此时可叠加border作为后备
响应式Grid切换时,焦点管理容易断裂
当媒体查询把grid-template-columns: 1fr 1fr改成1fr(从双列变单列),DOM结构没变,但视觉流变了。用户可能正按Tab从左列最后一个项跳到右列第一个项,切换后这两个项在视觉上变成上下关系,但焦点顺序还是按原DOM顺序走,造成“跳空感”。
- 这不是Grid的bug,而是响应式布局固有复杂性;无法靠CSS自动修复
- 若必须保证视觉流与焦点流一致,需用JS监听
resize并动态调整tabindex顺序(慎用,易引入可访问性风险) - 更稳妥的做法:保持主内容区域的DOM顺序始终符合阅读逻辑(比如顶部导航→主内容→侧边栏→页脚),让Grid只负责“怎么摆”,不负责“怎么读”
Grid的键盘导航高亮看似简单,实际卡点都在HTML语义、可聚焦性判断和gap与outline的像素级配合上。最容易被忽略的是:你花十分钟调好grid-template-areas,却忘了给那个div.card加tabindex="0"——结果测试时发现键盘用户根本点不到它。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











