grid-template-rows 无法实现多级折叠动画,因其属离散式布局属性,不支持 transition;应改用 max-height + overflow 方案,并确保各层 wrapper 尺寸、溢出与网格占位同步。

grid-template-rows 本身不能直接做多级折叠动画——你写 grid-template-rows: 0fr 1fr → grid-template-rows: 1fr 1fr,浏览器只会突变,不会补帧。这不是写法问题,是 CSS 规范明确禁止对这类布局定义属性做 transition。
为什么用 grid-template-rows 做折叠菜单会失败
常见错误现象:点击后子菜单瞬间出现/消失,没有缓动;或者根本不动,控制台也无报错。这是因为 grid-template-rows 属于「离散式布局声明」,不是数值型可插值属性。即使全用 px 或 fr,Chrome/Firefox/Safari 都不支持过渡。
容易被忽略的点:0fr 看似合理,但它只在 display: grid + 显式定义 + 子项占位时才能参与轨道分配;而多级菜单里,子 .submenu 往往是嵌套容器,不是父网格的直接子项——这直接导致 grid-template-rows 动画条件不满足。
真正能动的方案:用 max-height + overflow 模拟,同时保留 Grid 结构
核心思路:让菜单项保持 Grid 占位(不破坏布局流),但靠高度过渡实现视觉展开。需要一个 wrapper 包裹可折叠内容,并控制其 max-height 和 overflow。
立即学习“前端免费学习笔记(深入)”;
- 给每个可展开的
.submenu外层加<div class="expand-wrapper">,它才是网格直接子项 -
.expand-wrapper初始设max-height: 0、overflow: hidden、transition: max-height 0.3s ease - 展开时 JS 读取子内容的
scrollHeight,设为max-height值;收起时再设回0 - 别用
height: auto—— 它不可动画,且会撑开父网格轨道,破坏对齐
嵌套子菜单裁剪问题:overflow: visible 必须穿透到最外层容器
多级菜单横向展开(比如从侧边栏向右弹出二级)时,如果父容器(如 .sidebar)没设 overflow: visible,子菜单会被硬裁切——这不是 z-index 能解决的,是布局阶段的空间截断。
-
.sidebar必须显式声明overflow: visible - 如果
.sidebar是 Flex 子项,还要检查其父 Flex 容器是否误设了overflow: hidden或auto - 不要用
visibility: hidden替代display: none控制显隐——前者保留空间,会导致网格轨道空置、错位
多级折叠菜单最难的不是展开逻辑,而是确保每一层 wrapper 的尺寸控制、溢出处理和网格占位三者同步。一旦某一层漏掉 overflow: hidden 或误用 display: none,整个动画链就会断裂,且很难定位是哪一层出了问题。


















