:placeholder-shown + transform 可实现纯 CSS 浮动标签动画,需满足 placeholder 存在、label/input 正确关联、label 或父容器设 position: relative 三前提;它比 :focus 更精准判断输入状态,配合 :valid 覆盖 required 校验,且仅对 transform/opacity 做过渡以保障性能与可访问性。

直接用 :placeholder-shown + transform 就能实现干净、语义化、无需 JS 的浮动标签动画,但必须满足三个前提:input 有 placeholder(哪怕空格),label 和 input 正确关联(for/id 或嵌套),且 label 必须设 position: relative 或父容器设 position: relative。
为什么 :placeholder-shown 是关键状态判断依据
它比单纯依赖 :focus 更可靠——用户输入后失焦,label 还得浮着;而 :placeholder-shown 在 placeholder 可见时为 true,一旦输入内容(哪怕一个空格),它就变成 false,正好触发上浮。配合 :valid 还能覆盖 required 校验通过的场景。
-
input:placeholder-shown + label→ label 保持在框内原始位置 -
input:not(:placeholder-shown) + label→ label 上浮缩放 - 如果 input 带
required,可加input:valid + label强化非空态表现
transform: translateY() 必须搭配 position: relative
常见错误是只写 transform: translateY(-1.5em) 却没给 label 设定位上下文,结果文字“飘走”或消失。transform 不会改变文档流,但若无 position: relative(或 absolute/fixed),浏览器默认以初始包含块为基准,导致偏移不可控。
- label 默认应设
position: relative,再用transform控制位移 - 不要用
top替代transform—— 它会触发重排,动画卡顿,尤其在 iOS Safari 中明显 - 推荐组合:
transform: translateY(-1.6em) scale(0.85)(初始)→transform: translateY(-2em) scale(1)(上浮后)
过渡动画只对 transform 和 opacity 做 transition
写成 transition: all 0.2s ease 看似省事,实则埋雷:font-size、color、top 等属性变化都会触发 layout,拖慢渲染。现代浏览器对 transform 和 opacity 有合成层优化,不重排不重绘。
立即学习“前端免费学习笔记(深入)”;
- 正确写法:
transition: transform 0.2s ease, opacity 0.2s ease - label 初始
opacity: 0.7,上浮后opacity: 1,避免视觉突兀 - input 必须预留
padding-top(如1.4em),否则上浮后的 label 会被输入文字顶穿
兼容性兜底和可访问性容易被忽略
:placeholder-shown 在 IE 完全不支持,iOS Safari 15.4 之前存在输入法弹出时不触发的问题。更隐蔽的是:label 若没和 input 关联(for/id 不匹配或缺失),屏幕阅读器无法将提示文字与输入框绑定,WCAG 会失败。
- 降级方案不是加 JS,而是确保
input:focus + label规则仍存在,作为基础聚焦反馈 - label 内文本必须有意义,不能仅靠视觉隐藏(如
aria-hidden="true") - 若用空格占位符
placeholder=" ",要确认它不会被自动化测试工具误判为“无提示”


















