css transition必须写在label初始状态而非:focus规则中,否则动画失效;label位移需用transform配合position: relative;上移条件应为input:focus + label或input:not(:placeholder-shown) + label;避免半像素导致文字模糊;ios safari placeholder闪回需js监听input事件加.has-value类兜底。

input:focus时label上移动画失效?检查伪类优先级和transition位置
动效卡住不动,大概率是transition没写在label的**初始状态**上,而写在了:focus触发后的规则里。CSS transition必须定义在“始终存在”的基础样式中,否则浏览器无法补全中间帧。
常见错误写法:label:focus { transition: transform 0.2s; } —— label本身不支持:focus,这个规则根本不会生效。
- 正确做法:把
transition写在label默认样式里,例如label { transition: transform 0.2s ease; } - label位移靠
transform: translateY(-1.5rem)实现,但必须配合position: relative(否则transform无效) - 别用
margin-top或top做位移——它们会触发重排,动画更卡,且和placeholder-shown切换时容易跳变
:placeholder-shown和:focus冲突?用:not()组合避免label误判
当input有值但还没失焦,placeholder已消失,:placeholder-shown为false;此时若只靠:focus控制label位置,label会回落——这不是bug,是逻辑本该如此。但用户期望“有内容就保持上移”,得叠加判断。
真实场景中,label该上移的两种情况是:输入框获得焦点,或已有输入内容。不能只盯一个伪类。
立即学习“前端免费学习笔记(深入)”;
- 推荐组合:
input:focus + label, input:not(:placeholder-shown) + label - 注意
:not(:placeholder-shown)在Chrome/Firefox中表现一致,但Safari 15.4之前对空格输入(如只打了空格)识别不准,建议加input:not(:placeholder-shown):valid + label兜底 - 别用
input:valid单独判断——没设required或pattern时它永远是false
label文字模糊、边缘发虚?transform导致像素对齐失败
用transform: translateY()后label偶尔出现毛边,尤其在Retina屏或缩放125%时,本质是元素被渲染在非整数像素坐标上。
- 加
will-change: transform不一定有用,反而可能引发层叠上下文问题 - 更稳的解法:用
translateY(-1.4rem)代替-1.5rem,避开半像素渲染(rem基于font-size,易出小数) - 或者改用
calc(-1rem - 4px),确保最终值是整数像素 - 如果label用了
font-smoothing: antialiased,记得在动效中也保留,否则位移前后文字质感会突变
移动端iOS Safari placeholder消失延迟?监听input事件补位
iOS Safari有个隐藏行为:软键盘弹起瞬间,:placeholder-shown会短暂为true,哪怕input已有值——导致label闪回。这不是CSS能完全解决的,得加JS干预。
- 监听
input事件,当input.value.trim() !== ''时,给父容器加has-value类 - CSS里写
.has-value label强制上移,覆盖掉伪类的误判 - 别监听
change——它不触发即时输入,用户打字时动画就断了 - 注意防抖:连续输入不用每键都重绘,
requestAnimationFrame比setTimeout更准
动效看着简单,但跨浏览器下placeholder状态、transform渲染、事件时机三者咬合很紧。最容易被忽略的是iOS那个placeholder闪回——不真机测,光看Chrome开发者工具根本发现不了。










