直接对 grid-template-columns 做 transition 无效,因 fr 单位不可插值;应改用 width + min-width: 0 + overflow: hidden 实现平滑动画,并通过媒体查询切换 width 而非 grid-template-columns。

直接对 grid-template-columns 做 transition 无效
很多人一上来就写 transition: grid-template-columns 0.3s,结果发现菜单“啪”一下就消失,毫无动画。这是因为 fr 单位(比如 0fr 1fr)不是可插值的长度类型——浏览器无法在两个比率之间做线性过渡,0fr 实质是“无尺寸”状态,不是数值,transition 会静默失效。
用 width + min-width: 0 + overflow: hidden 替代轨道动画
真正能平滑过渡的是元素自身的 width(或 max-width),所以要把折叠逻辑从 Grid 轨道定义转移到菜单容器自身上:
PigX UI Pro 前端开发指南 - Vue 3 + TypeScript + Element Plus。当用户提到 PigX UI、PigX 前端、lgb-mgui 项目、Vue 3 企业级后台开发、Element Plus 后台开发时使用此技能。
- Grid 容器固定两列布局:
grid-template-columns: minmax(0, 1fr) minmax(0, 3fr),不随状态变化 - 菜单栏(如
.nav-sidebar)设初始width: 240px,折叠时改为width: 0 - 必须同时加
min-width: 0和overflow: hidden,否则子内容会撑开容器,width: 0形同虚设 - 给
width加transition: width 0.25s ease-in-out,动画立刻生效
响应式断点里别改 grid-template-columns,只切类名
在 @media (max-width: 768px) 里直接覆盖 grid-template-columns,会导致动画中断、布局跳变。正确做法是:
- 移动端默认折叠:
.nav-sidebar { width: 0; } - 桌面端恢复:
@media (min-width: 769px) { .nav-sidebar { width: 240px; } } - 避免用
display: none切换——它会清空渲染树,transition失效;改用visibility: hidden配合width: 0和opacity: 0(如需淡出) - 如果菜单含
position: absolute的下拉项,折叠时记得加pointer-events: none,否则仍可点击
JavaScript 切换类名时注意 DOM 渲染时机
直接 element.classList.toggle('collapsed') 够用,但如果你依赖折叠后计算尺寸(比如调整右侧内容 margin),得等重排完成:
- 不要在
toggle后立刻读offsetWidth,此时浏览器还没重绘 - 需要精确时机时,用
getComputedStyle(element).width或requestAnimationFrame包一层 - 若菜单内有
transform元素(如下拉箭头旋转),确保它不干扰定位上下文,否则折叠时下拉项可能错位
width,而不是交给 fr。这点容易被忽略,但决定了动画是否真实存在。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










