:placeholder-shown 不能直接实现悬浮标签,因其仅在输入框有 placeholder 且为空时生效,而悬浮标签需在聚焦或非空时仍上浮;须组合 :focus、:not(:placeholder-shown) 等状态并通过兄弟选择器控制标签。

为什么 :placeholder-shown 不能直接实现“悬浮标签”效果
它只在输入框有 placeholder 且内容为空时生效,一旦用户开始输入或聚焦,:placeholder-shown 就立刻消失——而悬浮标签(floating label)需要在聚焦或非空时仍保持上浮状态。单纯依赖这个伪类会漏掉 :focus 和 :not(:placeholder-shown) 两种关键状态。
正确组合状态:聚焦 + 非空 + 占位符存在
浮动标签需同时响应三种情况:输入框获得焦点、已有内容、placeholder 仍在(即未被 JS 清除)。推荐用以下复合选择器控制标签上浮:
input:focus + label,
input:not(:placeholder-shown) + label,
input:not(:placeholder-shown):focus + label {
transform: translateY(-1.2em) scale(0.85);
color: #333;
}
-
input:focus + label覆盖聚焦但内容为空的场景(此时:placeholder-shown仍为 true,但用户已交互) -
input:not(:placeholder-shown) + label覆盖有输入内容的情况(placeholder 自动隐藏,该伪类失效) - 最后一条是冗余加固,避免某些浏览器对伪类组合解析不一致
HTML 结构必须严格满足兄弟选择器前提
:placeholder-shown 只能作用于 <input> 元素自身,要影响标签必须靠 CSS 选择器关系。标签必须紧跟在 input 后面,且是其**下一个兄弟元素**:
<div class="field"> <input type="text" placeholder="邮箱" required><label>邮箱</label> </div>
- 不能把
<label></label>放在<input>前面(+不匹配前驱) - 不能中间插入其他元素(如图标、错误提示),否则
+失效;改用~或 JS 控制 - placeholder 属性不能缺失——没有
placeholder,:placeholder-shown永远不匹配
兼容性与降级要点
Firefox 51+、Chrome 47+、Safari 15.4+ 支持 :placeholder-shown,但 Safari 早期版本对 :not(:placeholder-shown) 解析不稳定。实际项目中建议:
- 始终保留
placeholder属性,哪怕只是空格placeholder=" "(避免 iOS Safari 下伪类完全不触发) - 对旧版 Safari 加一层
input:focus + label保底 - 不要依赖
:placeholder-shown做必填校验逻辑——它只反映 placeholder 显示状态,和值是否有效无关
真正麻烦的是 placeholder 文本和 label 文本重复带来的可访问性问题,这得靠 aria-label 或隐藏 placeholder 配合 JS 来解决,不是纯 CSS 能兜住的。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











