width过渡失效主因是起始值为auto或百分比,无法插值导致跳变;应改用max-width过渡或transform替代,兼顾兼容性与性能。

直接改 width 做点击拉长,90% 的失败都源于起始值是 auto 或百分比——浏览器无法对非确定值插值,动画直接跳变。
为什么 width 过渡经常不生效
常见写法:
input {
width: auto;
transition: width 0.3s;
}
input:focus {
width: 240px;
}
问题就出在 auto:它不是可动画的 CSS 值,浏览器跳过过渡,直接渲染目标尺寸。即使你用 width: 100%,父容器宽度一变,起始值就不固定,插值照样失败。
- 起始值必须是明确单位:如
px、em、rem(比如width: 50px) -
transition必须写在默认状态(非:focus),否则首次聚焦不会触发 - 避免混用
width和flex控制逻辑,容易冲突
用 max-width 替代 width 更稳妥
它允许内容自然伸展,又支持平滑过渡,兼容性好(IE10+),且不依赖父容器精确尺寸。
立即学习“前端免费学习笔记(深入)”;
.search-input {
padding: 8px 12px;
border: 1px solid #ccc;
border-radius: 4px;
max-width: 140px;
transition: max-width 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}
.search-input:focus {
max-width: 280px;
outline: none;
border-color: #007bff;
}
-
max-width过渡只在「收缩」或「扩张」方向起作用;若内容很短,它不会强制撑满 280px - 推荐用
cubic-bezier(0.4, 0, 0.2, 1),比ease更顺滑,适合轻量交互 - 务必加
outline: none(或自定义 focus outline),否则原生蓝色边框会和你的border叠加
移动端点击无反应?检查 :focus 触发条件
iOS Safari 和部分安卓浏览器中,:focus 在 <input> 上默认只对可编辑元素生效。结构或样式稍有偏差,就会静默失败。
- 确保
<input type="search">没被pointer-events: none或tabindex="-1"阻断 - 如果用了
<label>,确认for属性值与input的id严格匹配(大小写敏感) - 在 iOS 上,某些情况下需给
input加cursor: text才能唤起软键盘并触发focus - 别依赖
:focus-within做主逻辑——它在旧版 Android WebView 中支持差
过渡卡顿?优先用 transform 替代 width
重排(reflow)开销大,尤其在快速连点或 flex 容器中。transform 走合成层,性能更稳。
.search-input {
transform: scaleX(0.3);
transform-origin: left center;
transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.search-input:focus {
transform: scaleX(1);
}
- 配合
width: 100%和box-sizing: border-box使用,视觉连贯 - 注意:scale 不改变文档流,若需影响布局(如挤压旁边元素),仍得靠
width或flex - 真正线上项目里,纯
width方案容易在响应式断点或快速操作时错位——这点最容易被忽略


















