可行,但必须每级容器显式声明display: grid,且小屏下须用display: none控制子菜单显隐;只设外层grid会导致子菜单错位,因grid上下文不穿透dom层级,span列写法易失控,固定列轨道+显式grid-column定位更可靠。

直接说结论:用 display: grid 嵌套实现多层级导航菜单是可行的,但必须每级容器显式声明 display: grid,且不能依赖 visibility: hidden 或 opacity: 0 控制子菜单显隐——它们不释放布局空间、不阻断键盘焦点,会导致可访问性断裂。
为什么只给最外层设 grid,子菜单就错位或堆在左上角
Grid 上下文不会自动穿透 DOM 层级。父容器设了 display: grid,它的直系子元素才进入该网格;子菜单(比如 .submenu)若只是 li 的后代,而非网格项,grid-column 规则完全无效。
- 常见错误写法:
.sidebar { display: grid; },然后期望.submenu li能响应grid-column: 2 - 正确做法:每个可展开层级都需独立设为网格容器,例如:
.submenu-wrapper { display: grid; }和.submenu { display: grid; } - 嵌套越深,漏掉某一级
display: grid的概率越高,错位表现就是子菜单挤成一团、定位漂移、或完全不可见
用 grid-column 实现横向分级时,为什么 span 写法容易翻车
grid-column: span 2 看似省事,但嵌套层级一变,列轨道计算就失控。二级菜单设 span 2,三级再套一层,实际跨度变成 4,超出容器宽度后触发换行或溢出,视觉上就是菜单“断开”或“压住下面内容”。
- 推荐做法:顶层容器用固定列轨道,例如
grid-template-columns: 240px 240px 240px - 一级菜单项默认占第 1 列:
grid-column: 1 - 二级菜单强制进第 2 列:
.submenu[data-level="2"] { grid-column: 2; } - 三级菜单进第 3 列:
.submenu[data-level="3"] { grid-column: 3; } - 这样位置稳定,不随 DOM 深度变化而偏移
移动端下拉菜单必须用 display: none,而不是 visibility: hidden
小屏下如果只用 visibility: hidden 隐藏子菜单,它仍在渲染流中:占用空间、影响滚动高度、屏幕阅读器可读、Tab 键仍会聚焦到隐藏项里——这违反 WCAG 2.1 标准。
- 正确响应式逻辑:在
@media (max-width: 767px)中统一设.submenu { display: none; } - JS 展开时,仅给当前路径上的那一级加
.submenu.active { display: grid; } - 同时清除同级其他
.submenu的active类,避免多级同时显示 - 别用
opacity: 0+pointer-events: none替代——它不解决焦点和语义问题
真正难的不是写对 grid-column,而是确保每一级容器都“知道自己是个网格”,以及在响应式切换时彻底从渲染树中移除非活跃菜单——这两点漏掉任何一处,菜单就会在真实用户场景中失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











