
flex-grow 动画为什么默认不生效
因为 flex-grow 是一个“计算后生效”的布局属性,不是 CSS 动画属性,浏览器不会对它的变化做插值过渡。直接写 transition: flex-grow 0.3s 看起来没反应,不是你写错了,是它本来就不支持。
常见错误现象:flex-grow 突然跳变、展开时无过渡、控制台没报错但视觉毫无动画感。
- 真正能过渡的只有数值型可动画属性:比如
width、max-height、opacity、transform -
flex-grow的本质是分配剩余空间的比例系数,渲染引擎在 layout 阶段才计算,无法逐帧插值 - 想靠它做手风琴,得换思路——用它“配合”可动画属性,而不是指望它自己动
用 max-height + overflow 实现可靠的手风琴伸缩
这是目前最兼容、最可控的做法,尤其适合图片画廊这种高度不确定但结构固定的场景。核心是把高度变化“骗”成一个可过渡的 CSS 属性。
使用场景:图片尺寸不统一、需要响应式、要支持任意数量子项、不依赖 JS 控制高度。
立即学习“前端免费学习笔记(深入)”;
- 给每个画廊项设初始
max-height: 0和overflow: hidden - 展开时设为足够大的固定值(如
max-height: 500px),确保所有图片都能完全显示 - 搭配
transition: max-height 0.35s ease-in-out,过渡自然 - 注意:不能用
height: auto过渡,CSS 不支持auto插值
img-gallery-item {
max-height: 0;
overflow: hidden;
transition: max-height 0.35s ease-in-out;
}
img-gallery-item.active {
max-height: 500px; /* 要大于最大可能高度 */
}transition 监听不到 flex-grow 变化?改用 transform 缩放模拟伸缩感
如果坚持用 Flex 布局且想保留“弹性扩张”的视觉联想,可以放弃监听 flex-grow,转而用 transform: scale() 或 transform: scaleX() 做轻量级动效。
性能影响小,GPU 加速友好,且能和 flex-grow 共存——前者负责动效,后者负责布局分配。
- 给图片容器加
transform-origin: left center,让缩放从左侧出发,更像手风琴拉开 - 展开时设
transform: scaleX(1.2),收缩回scaleX(1),配合transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1) - 别用
scaleY拉伸图片,会失真;优先选scaleX或纯scale配合 padding 控制留白 - 注意:
transform不影响文档流,所以必须配合flex-grow或其他布局逻辑来保证其他项正确重排
图片画廊手风琴的真实复杂点:高度动态 + 图片加载延迟
实际项目里最难搞的不是过渡本身,而是图片还没加载完时就触发了展开——这时 max-height 设小了会裁切,设大了收不紧,留白难看。
容易被忽略的地方:
- 图片加载完成前,无法准确知道真实高度,
getBoundingClientRect()返回的是占位高度 - 不要在
img.onload后立刻设置max-height,否则可能触发两次 layout,造成闪动 - 稳妥做法:先用
max-height: 0→ 触发展开 → 等图片加载完 →offsetHeight读取真实高 → 再设一次max-height并移除内联样式交还给 CSS 过渡 - 如果用
transform方案,这个问题影响较小,但缩放中心点仍需按加载后的尺寸重新计算










