:placeholder-shown 仅在 input 或 textarea 具有 placeholder 属性且其 value 为空字符串(非空格)时生效,响应原生占位符显示状态,不适用于自定义 placeholder 或无 placeholder 属性的元素。

什么是 :placeholder-shown 的实际作用范围
:placeholder-shown 只在 <input> 或 <textarea> 有 placeholder 属性、且当前值为空时才匹配。它不是“占位符存在就生效”,而是“placeholder 正在显示才触发”。一旦用户输入哪怕一个空格,或者用 JS 设置了 value = "" 但焦点未离开,它都可能失效。
- 必须带
placeholder属性,否则伪类不生效(哪怕 DOM 里写了,也要确保 HTML 中存在) - 对
type="number"等控件,输入非法值(如字母)时 value 为空字符串,:placeholder-shown仍会激活 - 不能用于自定义 placeholder(比如用
<span>模拟的),它只响应原生 placeholder 渲染逻辑
浮动标签的基本 HTML 结构怎么写才可靠
浮动标签需要 label 能“感知”输入状态,最稳妥的方式是把 <label> 放在 <input> 后面,并用相邻兄弟选择器 + :placeholder-shown 控制位移。不要依赖 for/id 关联去驱动样式,那无法触发 CSS 状态切换。
- 结构示例:
<div class="field"> <input placeholder="邮箱" type="email"> <label>邮箱</label> </div>
-
label必须紧跟input,中间不能有其他元素(包括注释、换行符在某些解析下也可能破坏相邻关系) - 避免用
position: absolute把 label 压到 input 上方再靠 transform 浮动——这样容易和 focus/invalid 状态冲突
如何用 :placeholder-shown 配合 :focus 处理边界状态
仅靠 :placeholder-shown 无法覆盖所有情况:用户输入后删除内容、输入空格再删、或表单初始加载时已有默认值。必须叠加 :focus 和 :valid(对必填字段)才能让标签真正“浮起并停留”。
- 推荐组合写法:
.field input:focus + label, .field input:not(:placeholder-shown) + label, .field input:valid + label { transform: translateY(-1.2em) scale(0.85); } -
:not(:placeholder-shown)比:placeholder-shown的否定更可靠——后者在 Safari 中对某些 type(如date)支持不稳定 - 如果 input 有
required,:valid在非空时为 true;没required时可改用:not(:blank)(需检查浏览器支持)
为什么 label 浮动后文字模糊或抖动
常见原因是 transform 引发 subpixel 渲染问题,尤其在 Chrome 和旧版 Safari 下。不是动画没写好,而是坐标没对齐到物理像素。
立即学习“前端免费学习笔记(深入)”;
- 给 label 加
transform: translateZ(0)或backface-visibility: hidden强制 GPU 加速(但慎用,可能影响可访问性) - 优先用
top+font-size缩放代替transform,例如:.field input:focus + label { top: -0.8em; font-size: 0.85em; } - 确保父容器
.field有明确position: relative,否则 label 的定位基准会错乱
:placeholder-shown 的触发时机和 value 的同步节奏经常不一致,得靠 JS 补漏。


















