grid嵌套需每级容器显式声明display: grid;grid-column应配合固定列轨道定位而非span;小屏须用display: none控制子菜单显隐;父容器overflow必须设为visible防裁剪。

Grid 嵌套结构必须满足父子容器显式声明 display: grid
直接在 .sidebar 上写 grid-template-rows 无法让子菜单自动按层级展开——Grid 不会隐式继承或传播网格上下文。每一级菜单容器(如一级菜单项、二级子菜单、三级弹出层)都必须独立设为 display: grid,否则 grid-area 或 grid-column 规则无效。
常见错误是只给根侧边栏设 Grid,然后指望 .submenu 里的 li 自动对齐到某列。结果是子菜单堆叠在左上角,或完全不响应 grid-column-start。
实操建议:
- 一级菜单容器:
.sidebar { display: grid; grid-template-columns: 1fr; } - 每个可展开项(带子菜单的
li)需包裹一层<div class="submenu-wrapper">,并设 <code>display: grid - 子菜单本身(
.submenu)也要声明display: grid,才能用grid-column: 2横向铺开 - 顶层
.sidebar定义: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; } - 移动端(
max-width: 767px):统一设.submenu { display: none; } - 只保留当前展开路径上的那一级
.submenu,用.submenu.active { display: grid; } - JS 控制展开时,同步清除其他同级兄弟的
active类,防止多级同时显示 -
.sidebar父容器是否设了overflow: hidden?删掉或改为visible - 中间任意一层 wrapper(比如
.menu-group)是否加了overflow: hidden?这是最常被忽略的裁剪源 - 不要用
clip-path或mask遮盖溢出——它们会让子菜单不可点击、不可聚焦
grid-column 控制横向分级时,避免用 span 硬编码列数
写 grid-column: span 2 看似方便,但嵌套变深后极易错位:二级菜单设了 span 2,三级再套一层就变成 span 4,超出容器宽度,触发换行或溢出。
更可靠的做法是固定列轨道定义 + 显式定位:
这样每级位置可控,且不会因 DOM 层级变动而偏移。
响应式断点中,Grid 分级布局必须配合 display: none 切换,而非仅靠 grid-column
小屏下如果只把 .submenu 的 grid-column 改成 1,它仍会渲染在 DOM 中、占用空间、影响滚动和焦点流。用户看不到,但屏幕阅读器能读,键盘 Tab 仍会卡在隐藏菜单里。
正确做法是在媒体查询中彻底控制显隐逻辑:
别依赖 visibility: hidden 或 opacity: 0 替代 display: none ——前者不释放空间,后者不阻断焦点。
子菜单溢出被裁剪?大概率是父容器漏了 overflow: visible
Grid 容器默认 overflow: auto 或 hidden(尤其在 flex 包裹的侧边栏里),一旦子菜单用 grid-column: 2 向右延伸,就会被左侧父容器截断,只显示半截。
必须逐级检查:
Grid 分级本身不解决溢出问题,它只是定位工具;溢出控制永远由父容器的 overflow 决定。











