子菜单对不齐父项列线,是因为Grid上下文不继承,需逐级显式声明display: grid;父容器必须明确定义grid-template-columns(不能仅用auto-fit),中间层禁用gap等干扰项,否则隐式轨道会切断对齐链。

为什么子菜单总对不齐父项列线?
因为 Grid 上下文不继承,.submenu 里的 grid-column: 2 不会自动参考外层的列轨道。常见表现是子菜单堆在左上角、文字重叠、或完全不响应定位指令。
- 必须逐级显式声明 display: grid:父容器、中间包裹层(如 .submenu-wrapper)、子菜单本体都得设
- 父容器必须明确定义 grid-template-columns(不能只用 auto-fit 或 grid-auto-columns)
- 中间层若用了 gap、grid-auto-rows 或空标签,会生成隐式轨道,切断对齐链
用 subgrid 还是显式列轨道?
两者适用场景不同,别混用。
- 想穿透多层对齐顶层列线(比如图标始终对齐 [icon] 命名线),必须用 subgrid,且中间层也得写 grid-template-columns: subgrid 和 grid-template-rows: subgrid
- 如果只是三级以内、列数固定(如最多三列),推荐显式三列轨道:grid-template-columns: 240px 240px 240px,再用 grid-column: 1 / 2 / 3 控制层级,更可控、兼容性更好
- grid-column: span 2 在嵌套中极易失控:二级菜单 span 2,三级再套一层就变成实际占 4 列,直接溢出
移动端子菜单为啥点不到或闪退?
根本不是 hover 逻辑问题,而是热区断裂或渲染残留。
- 小屏下不能只改 grid-column 或靠 visibility: hidden 隐藏子菜单——它仍占 DOM 空间、影响 Tab 键焦点、屏幕阅读器可读
- 正确做法:媒体查询中统一设 @media (max-width: 767px) { .submenu { display: none; } },仅当前展开路径上的节点加 .submenu.active { display: grid; }
- 确保父容器(如 .sidebar)设了 overflow: visible,否则横向铺开的子菜单会被裁剪——尤其当父容器本身是 flex 子项时,还要检查其 flex 父容器没设 overflow: hiddenJS 展开时容易忽略的对齐细节
DOM 结构变化后,Grid 轨道不会自动重映射,错位常发生在动态插入后。
- 展开子菜单前,确保它已被插入到正确父节点下(不是 document.body 下挂载),否则脱离原 Grid 上下文
- 若用 JS 动态添加 data-level="3",记得同步更新对应样式规则:.submenu[data-level="3"] { grid-column: 3; }
- 不要用 transform: translateX() 或 will-change: transform 优化动画——它们会改变包含块,导致 position: absolute 子菜单定位偏移
- 检查 Chrome DevTools 的 Grid Inspector 是否勾选 “Show line names”,能立刻确认命名线是否来自顶层容器,而不是中间层伪造的
[icon] 命名线),必须用 subgrid,且中间层也得写 grid-template-columns: subgrid 和 grid-template-rows: subgrid
- 如果只是三级以内、列数固定(如最多三列),推荐显式三列轨道:grid-template-columns: 240px 240px 240px,再用 grid-column: 1 / 2 / 3 控制层级,更可控、兼容性更好
- grid-column: span 2 在嵌套中极易失控:二级菜单 span 2,三级再套一层就变成实际占 4 列,直接溢出
移动端子菜单为啥点不到或闪退?
根本不是 hover 逻辑问题,而是热区断裂或渲染残留。
- 小屏下不能只改 grid-column 或靠 visibility: hidden 隐藏子菜单——它仍占 DOM 空间、影响 Tab 键焦点、屏幕阅读器可读
- 正确做法:媒体查询中统一设 @media (max-width: 767px) { .submenu { display: none; } },仅当前展开路径上的节点加 .submenu.active { display: grid; }
- 确保父容器(如 .sidebar)设了 overflow: visible,否则横向铺开的子菜单会被裁剪——尤其当父容器本身是 flex 子项时,还要检查其 flex 父容器没设 overflow: hiddenJS 展开时容易忽略的对齐细节
DOM 结构变化后,Grid 轨道不会自动重映射,错位常发生在动态插入后。
- 展开子菜单前,确保它已被插入到正确父节点下(不是 document.body 下挂载),否则脱离原 Grid 上下文
- 若用 JS 动态添加 data-level="3",记得同步更新对应样式规则:.submenu[data-level="3"] { grid-column: 3; }
- 不要用 transform: translateX() 或 will-change: transform 优化动画——它们会改变包含块,导致 position: absolute 子菜单定位偏移
- 检查 Chrome DevTools 的 Grid Inspector 是否勾选 “Show line names”,能立刻确认命名线是否来自顶层容器,而不是中间层伪造的
data-level="3",记得同步更新对应样式规则:.submenu[data-level="3"] { grid-column: 3; }
- 不要用 transform: translateX() 或 will-change: transform 优化动画——它们会改变包含块,导致 position: absolute 子菜单定位偏移
- 检查 Chrome DevTools 的 Grid Inspector 是否勾选 “Show line names”,能立刻确认命名线是否来自顶层容器,而不是中间层伪造的


















