:placeholder-shown 是唯一纯 css 可靠检测输入框内容为空的方式,但需同时满足:有 placeholder 属性、value 为 ""、浏览器支持(safari ≥15.4);:empty 对 无效,因其为自闭合标签,无子节点,语义上永不匹配。

:placeholder-shown 是目前唯一能纯 CSS 检测输入框“内容为空”的可靠方式,但必须满足三个硬性条件:元素带 placeholder 属性、value 真正为空字符串("")、浏览器支持(Safari ≥15.4)。缺一不可,否则样式不生效。
为什么 :empty 对 <input> 完全无效
:empty 只匹配「没有子节点」的元素,而 <input> 是自闭合标签,内部永远没有子节点——所以它永远不为空,也永远不匹配 :empty。这不是兼容性问题,是语义根本错位。别试,没用。
常见错误现象:input:empty { display: none; } 在任何浏览器里都不起作用。
-
:placeholder-shown判断的是「占位符是否正在显示」,这恰好与value === ""且 placeholder 属性存在强相关 - 它不关心 placeholder 文本内容,哪怕写成
placeholder=" "(一个空格)也能触发 - 但
placeholder=""(空字符串)行为不一致:Chrome/Firefox 忽略,Safari 可能触发 → 应避免
:placeholder-shown 失效的典型场景和修复方法
它看起来简单,实际在真实项目里极易“突然不工作”,多数是因为 DOM 状态没对齐。
-
type="number"或type="date"清空后value可能为"",但 placeholder 不显示 → 伪类不匹配。修复:换用type="text"或 JS 回退 - React/Vue 受控组件中,state 更新了但 DOM 的
value属性未同步 →:placeholder-shown不响应。修复:确保<input value="{val}">中val是""而非null或undefined - 用户输入空格再删掉,
input.value可能变成" "(含空格)→ 占位符不显示,伪类失效。修复:监听input事件,实时执行el.value = el.value.trim()并触发事件 - Safari ≤15.3 不支持 → 必须加 JS 检测并降级,例如用
classList.toggle("is-empty", !el.value.trim())
怎么用 :placeholder-shown 控制兄弟元素或父容器样式
<input> 是替换元素,不支持 ::before/::after,所以想加提示文字、图标或切换按钮状态,必须靠结构配合。
- 控制紧邻兄弟:
input:placeholder-shown + .hint { display: block; },前提是 HTML 中.hint紧跟在<input>后面 - 控制提交按钮禁用态:
input:placeholder-shown ~ button[type="submit"] { opacity: 0.5; pointer-events: none; },注意用~(通用兄弟)而非+(相邻兄弟),因为按钮通常不在紧邻位置 - 控制外层容器:
.form-group:has(input:placeholder-shown) { border-color: #e53e3e; }(需确认目标环境支持:has()),否则改用 JS 添加 class - 别写
input:placeholder-shown::after—— 这行代码不会渲染出任何东西,纯属浪费调试时间
和 :focus、:valid 搭配时最容易踩的逻辑坑
它们不是互斥开关,而是不同维度的状态信号,混用时优先级和时机容易误判。
-
input:placeholder-shown:focus表示「刚点进去、还没输任何字符」,一旦敲下第一个键就立刻退出 —— 它不等价于「空且聚焦中」,因为删光内容后焦点还在,但伪类已失效 -
:placeholder-shown:not(:valid)永远不匹配:只要:placeholder-shown成立,value就是"",而""对required字段是:invalid,但对非required字段可能是:valid;关键是二者不能同时为真 —— 浏览器不允许 - 真实表单需要三层状态链:
:placeholder-shown(空)→:focus(正在输)→:valid/:invalid(输完校验),CSS 规则要分开写,别指望一个选择器包打天下 - 移动端 iOS Safari 对
:placeholder-shown的触发有延迟(尤其软键盘收起后),视觉反馈可能滞后半秒,这点在交互动效里必须预留余量
最常被忽略的一点:它只反映 DOM 层面的空值,不感知业务语义。用户粘贴零宽空格、全角空格、或者自动填充带不可见字符的内容,value.trim() 都可能失败,:placeholder-shown 就会静默退出。表单校验逻辑绝不能只靠它,JS 层的 isEmpty() 仍不可替代。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











