:placeholder-shown 无法单独实现浮动标签,需结合 :focus、:valid 等状态及 transition 动画,并严格保证 DOM 结构、placeholder 属性存在、label 定位与 pointer-events 设置,否则标签会异常掉落或失效。

:placeholder-shown 本身不能实现浮动标签效果,它只是一个状态信号——只在 input 或 textarea 有 placeholder 属性且当前值为空字符串(不含空格)时匹配。单靠它,标签动不了,也浮不起来。
为什么只写 :placeholder-shown 会失效
用户一聚焦、一输入、甚至粘贴一个全角空格,:placeholder-shown 就立刻为 false,label 瞬间掉回原位。常见错误是这样写:
input:placeholder-shown + label { transform: translateY(0); }
input:not(:placeholder-shown) + label { transform: translateY(-1rem); }
这会导致:输入文字 → 上浮;删光 → 掉回;再点进去(没删内容)→ 又掉回。体验断裂,根本不是“浮动”。
-
:placeholder-shown不响应:focus,无法捕获“空但已点击”的状态 - 它对
type="number"或type="date"在 Safari ≤15.4 中偶发不触发 - 输入空格、换行符、全角空格后,
value逻辑上仍为空,但伪类已失效 - IE 完全不支持;旧 Edge 需 16+ 才可用
input + label 结构必须严格相邻
所有基于 + 的选择器(如 input:focus + label)都依赖 DOM 顺序:label 必须紧跟在 input 后面,中间不能有任何元素——包括注释、换行符(某些解析下也会破坏)、图标、错误提示等。
- ✅ 正确:
<input placeholder="邮箱"><label>邮箱</label> - ❌ 错误:
<label>邮箱</label><input placeholder="邮箱">(+不选前驱) - ❌ 错误:
<input><span>icon</span><label>邮箱</label>(中间插了span)
若结构无法保证紧邻,+ 规则压根不生效,得换用 ~ 或 JS 控制。
必须带 placeholder 属性,哪怕值是空格
没有 placeholder 属性,:placeholder-shown 永远为 false——这不是 bug,是规范行为。JS 动态设置(如 input.setAttribute('placeholder', ''))在部分旧版 Safari 中也不触发。
- 可写
placeholder=" "(一个空格),既满足存在性,又避免显示干扰文本 -
type="hidden"、disabled、contenteditable元素上该伪类无效 -
label必须设position: relative,否则transform基准是视口,标签会飘出屏幕 - 记得加
pointer-events: none,否则label会挡住input点击
真正能撑起浮动的组合写法
要覆盖「空但聚焦」「非空失焦」「非空聚焦」三种关键状态,必须组合使用:
.field input { padding-top: 1.5rem; }
.field label {
position: absolute;
top: 0.75rem;
transition: transform 0.2s ease;
pointer-events: none;
}
.field input:placeholder-shown + label,
.field input:not(:placeholder-shown):not(:valid) + label {
transform: translateY(0);
}
.field input:focus + label,
.field input:valid + label {
transform: translateY(-1rem) scale(0.85);
}
-
:focus + label覆盖空但已交互的场景 -
:not(:placeholder-shown)比:valid更稳定(:valid在type="number"输入"0"或空格时可能不触发) - 如果字段不允许加
required,:valid就不可靠,只能靠 JS 监听input和blur动态切has-value类 - 动画必须加
transition,否则是瞬移,不是“浮动”
最难的不是写出那几行 CSS,而是理解 :placeholder-shown 只是个开关——它不管焦点、不校验、不区分空格和空值。所有状态边界都要手动补全,漏掉任意一种,UI 就卡在奇怪的位置。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











