:placeholder-shown 更适合判断输入框为空,因为 :empty 对 input 无效(input 是自闭合标签),而 :placeholder-shown 能准确响应 value 为空且 placeholder 可见的状态。

为什么 :placeholder-shown 比 :empty 更适合判断输入框为空
:empty 对 完全无效——它只匹配**没有子节点的元素**,而 是自闭合标签,永远不满足该条件。真正能响应“用户尚未输入”状态的是 :placeholder-shown:只要 placeholder 可见(即 value 为空字符串且未获得焦点,或获得焦点但仍未输入),该伪类就生效。
注意::placeholder-shown 不依赖 placeholder 文本是否存在,只要浏览器认为 placeholder “正在显示”,它就起作用。哪怕你写了 placeholder="",部分浏览器仍会触发该伪类(行为不一致,应避免空 placeholder)。
- 必须确保
有placeholder属性(哪怕只是占位符空格placeholder=" "),否则 Chrome/Firefox 均不触发 - Safari 15.4+ 才完整支持
:placeholder-shown,旧版 Safari 需用 JavaScript 回退 - 该伪类在
type="number"或type="date"上可能失效——这些类型在清空后 value 可能为"",但 placeholder 不一定显示,导致伪类不匹配
:placeholder-shown 的典型样式控制场景
最常见需求是:输入框为空时边框变红/加阴影/显示提示文字;一旦输入(或获得焦点并开始输入),样式立即恢复。这比监听 input 事件更轻量,纯 CSS 即可完成。
示例:给空状态加红色边框和底部提示
input {
border: 1px solid #ccc;
}
input:placeholder-shown {
border-color: #e53e3e;
}
input:placeholder-shown::after {
content: "请输入内容";
font-size: 0.8em;
color: #e53e3e;
display: block;
margin-top: 4px;
}
⚠️ 注意:::after 在 上无效(替换元素不支持伪元素),上面的写法不会生效。正确做法是配合外部 或额外 元素做提示,或者改用 input:placeholder-shown + .hint 这类兄弟选择器。
与 :focus 和 :valid 搭配时的优先级陷阱
单独用 :placeholder-shown 只能判断“空”,但真实表单需要区分:空 → 聚焦中 → 已输入 → 输入合法。这时容易误以为 :placeholder-shown:focus 能表示“聚焦但还没输”,其实它在用户点击后、尚未按键前就成立;而一旦输入一个字符,:placeholder-shown 立刻失效,不管内容是否合法。
-
input:placeholder-shown:focus:聚焦且 value === ""(最常用的“待填写”态) -
input:not(:placeholder-shown):valid:已输入且通过required/pattern校验(需设置pattern或required) -
input:not(:placeholder-shown):invalid:已输入但校验失败(如邮箱格式错)
关键点:浏览器对 :valid/:invalid 的判定默认是“非空即 valid”,除非你显式加了 required 或 pattern。所以没加 required 的 input,即使输错也不会触发 :invalid。
兼容性不足时的最小化 JS 回退方案
如果必须支持 Safari input 上加一个 class 控制空状态即可:
const inputs = document.querySelectorAll('input[placeholder]');
inputs.forEach(input => {
const updateEmptyState = () => {
input.classList.toggle('is-empty', input.value === '');
};
input.addEventListener('input', updateEmptyState);
input.addEventListener('blur', updateEmptyState);
updateEmptyState(); // 初始化
});
然后用 input.is-empty 替代 input:placeholder-shown 写样式。这样既保持 CSS 主体逻辑清晰,又只在必要时引入极简 JS,不破坏原有设计流。
真正容易被忽略的是 type 属性的影响——比如 type="number" 在清空后 value 是 "",但 placeholder 往往不显示,:placeholder-shown 就不会触发。这种情况下,只能靠 JS 判断 value 是否为空,别硬套伪类。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











