结论:flex-grow 不支持 transition,放大效果应使用 transform: scale() + z-index;若需空间变化可用可过渡的 flex-basis,但 scale 更直观可靠。

底部导航栏用 flex-grow 做点击放大?别这么做
直接说结论:flex-grow 本身不支持 CSS 过渡(transition),强行加 transition: flex-grow 0.3s 在绝大多数浏览器里无效或行为不可靠。你看到的“放大”大概率是视觉错觉,或是其他属性(比如 transform 或 font-size)在起作用,flex-grow 只是被动响应容器剩余空间变化。
为什么 flex-grow 不能过渡
flex-grow 是一个无单位的比例值(如 1、2),它不直接对应像素,而是参与 flex 容器内剩余空间的**分配计算**。浏览器不会对这个比例做插值动画,所以 transition 拿不到中间状态。
- Chrome / Edge 110+ 对
flex-grow的transition有极有限支持,但仅限于从0→1这类简单整数切换,且依赖父容器宽度固定 - Safari 和 Firefox 完全忽略
flex-grow的 transition 声明 - 即使“看起来动了”,实际是其他元素重排导致的闪烁或跳变,不是平滑缩放
真正可靠的做法:用 transform: scale() + z-index
底部导航项放大,本质是视觉层级和尺寸变化,transform 是专为此设计的高性能属性,支持硬件加速且可精确控制。
示例结构(简化):
<nav class="bottom-nav"><a href="#" class="nav-item">首页</a> <a href="#" class="nav-item">发现</a> <a href="#" class="nav-item active">我的</a> </nav>
CSS 关键部分:
.bottom-nav {
display: flex;
justify-content: space-around;
align-items: center;
height: 60px;
background: #fff;
box-shadow: 0 -2px 8px rgba(0,0,0,0.08);
}
<p>.nav-item {
display: flex;
flex-direction: column;
align-items: center;
color: #999;
font-size: 12px;
transition: transform 0.25s cubic-bezier(0.22, 0.61, 0.36, 1),
color 0.25s,
z-index 0.1s;
z-index: 1;
}</p><p>.nav-item.active {
transform: scale(1.25);
color: #007aff;
z-index: 3;
}</p>
-
transform: scale()独立于布局流,不影响其他 item 位置,避免 flex 重排抖动 -
z-index必须配合设置,否则放大的 item 可能被相邻项遮挡 - 用
cubic-bezier()调整缓动,比默认ease更贴合点击反馈感 - 不要给
.nav-item设固定宽高 ——scale会自动撑开,靠align-items: center居中即可
如果坚持要“占更多空间”,用 flex-basis 替代 flex-grow
想让选中项在 flex 行内“挤占”邻项空间,可以改用可过渡的 flex-basis(它对应的是基础主轴尺寸,单位明确):
.nav-item {
flex: 1 1 24%; /* 初始 flex-basis: 24% */
transition: flex-basis 0.25s;
}
<p>.nav-item.active {
flex-basis: 36%;
}</p>
- 必须显式写
flex-basis(或用flex简写),不能只靠flex-grow - 百分比值需确保总和 ≤ 100%,否则触发换行或溢出;建议用
calc()动态算,比如flex-basis: calc(33.333% - 2px) - 仍需配合
z-index和transform防止文字被裁切或层叠错乱
实际项目中,纯 flex-basis 扩展容易导致相邻图标/文字挤压变形,不如 scale 直观可控。放大效果的重点从来不是“占多大空间”,而是用户是否清晰感知到当前焦点 —— 这一点 transform 加颜色/阴影变化已经足够。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











