必须为input设置明确初始宽度(如180px)并写transition在默认状态,否则width动画失效;避免width与max-width混用、未设box-sizing:border-box或display:inline导致跳变。

input:focus 时用 CSS transition 实现平滑加宽
直接给 input 添加 :focus 状态下的 width 变化 + transition 就能实现,但必须满足几个前提,否则动画不触发或跳变。
- 确保
input默认有明确的width(不能靠内容撑开或依赖size属性) -
transition必须写在默认状态里,不是只写在:focus中;推荐写成transition: width 0.2s ease; - 避免同时设
min-width/max-width和width动画冲突——如果父容器窄,width: 100%在 focus 时扩到300px,但父容器只有200px,实际不会动 - 别用
size属性控制初始宽度,它和 CSSwidth混用会导致行为不可预测(尤其在 Safari 中)
示例写法:
input {
width: 180px;
padding: 8px 12px;
box-sizing: border-box;
transition: width 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
input:focus {
width: 280px;
}
为什么加了 transition 还是“啪”一下跳变
常见原因不是代码写错,而是浏览器没把 width 当作可过渡属性——根本在于初始 width 值没被解析为具体数值。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 写成
width: 100%→ focus 时设width: 300px:百分比到像素不是线性过渡,Chrome 直接跳,Firefox 可能卡顿 - 没设
box-sizing: border-box→padding和border会额外撑出尺寸,导致实际宽度计算混乱,transition 失效 - 用了
display: inline(默认值)→ 内联元素不支持width动画;必须显式设display: inline-block或block - 父元素有
overflow: hidden→ 宽度扩大时被裁剪,视觉上像没动
移动端点击后不触发 focus 动画怎么办
iOS Safari 和部分安卓浏览器中,input 获得焦点不等于立即触发 :focus 样式,尤其当页面缩放、字体过小或存在 user-scalable=no 时。
- 强制最小字号:
font-size: 16px,否则 iOS 会自动放大整个输入框,破坏 CSS 动画节奏 - 避免用
transform: scale()或zoom做“放大”,它们不触发:focus,且会偏移点击热区 - 不要依赖
onclick手动加 class —— 焦点可能晚于点击事件触发,造成闪烁或不同步 - 真要保兼容,可监听
focusin事件,用 JS 切换 class,但需注意 iOS 上focusin可能延迟 100ms+
想让加宽响应文字长度,而不是固定值
纯 CSS 做不到“随内容自适应加宽”,必须用 JS。但关键不是每输一个字就重算,而是控制好时机和重绘节奏。
- 监听
input事件(不是keydown),它覆盖中英文、粘贴、删除等所有输入场景 - 每次先清空内联
style.width,再用scrollWidth测量内容宽度,否则旧值会干扰 - 别直接设
width,改用min-width+max-width配合transition,防止抖动 - 移动端要注意:iOS Safari 的
scrollWidth对单行 input 常偏小,可加padding-right: 1px补偿
真正容易被忽略的,是过渡函数选型和初始宽度的锚定——用 cubic-bezier(0.25, 0.46, 0.45, 0.94) 比 ease 更顺,而初始 width 如果来自 calc(100% - 20px),在 flex 容器里可能因渲染顺序错乱导致第一次 focus 不动画。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










