必须写placeholder属性,因为:placeholder-shown仅在dom元素存在该属性时才启用状态判断逻辑;即使placeholder=""也合法有效,而缺失该属性则伪类永远不匹配。

为什么必须写 placeholder 属性,哪怕值为空
不写 placeholder,:placeholder-shown 伪类永远不匹配——这是硬性前提,不是可选项。浏览器只在 DOM 元素存在该属性时才启用该状态判断逻辑。
常见错误是删掉 placeholder 或设为 placeholder="" 后发现浮动失效,其实 placeholder="" 是合法且推荐的写法;用空格 placeholder=" " 也行,但容易被误删或压缩工具干掉。
-
type="hidden"、disabled、contenteditable元素上:placeholder-shown不生效 -
select元素没有:placeholder-shown,它靠option[disabled][selected]模拟 - IE 完全不支持,如需兼容,得 fallback 到 JS 监听
input和blur事件
input:not(:placeholder-shown) + label 为什么比 :focus 更可靠
:focus 只反映“当前是否聚焦”,一失焦标签就回落,盖住已输入内容;而 :not(:placeholder-shown) 表示“placeholder 已消失”,即用户至少输入了一个字符(含空格、换行符等),这个状态会持续到输入被清空为止。
它天然覆盖「已填」语义,无需 JS 维护状态变量,也不依赖表单验证规则(比如 required 或 pattern)。
- 用户粘贴带首尾空格的文本,
input.value.trim() === ""会误判为空,但:placeholder-shown立刻失效 -
input:valid在无required时对空字符串也返回 true,完全不可信 - 若
label不紧挨input,改用input:not(:placeholder-shown) ~ label,但需确保两者同级且在同一个父容器内
label 上浮动效卡住或飘走的三个定位前提
写 transform: translateY(-1.5em) 没反应?大概率是因为没设定位上下文。CSS transform 不会自动创建包含块,偏移基准是视口左上角,不是 input 边框。
-
label或其直接父容器必须设position: relative -
label自身要用position: absolute脱离文档流,否则会撑开布局 -
label的top/left值要配合transform使用,否则初始位置错乱
别用 % 单位做 transform 偏移量——它依赖父容器宽高,易抖动;统一用 px 或 em。
JS 动态填充后浮动标签不更新怎么办
编辑页回填数据时,input.value = "xxx" 不会自动触发 :placeholder-shown 状态重算。浏览器只在用户交互或 placeholder 属性变更时响应,DOM value 改变本身不触发重绘。
必须手动派发事件激活 CSS 状态:
input.value = "已回填内容";
input.dispatchEvent(new Event('input', { bubbles: true }));
- 仅设置
value不够,input事件才是关键信号 - 不要用
change事件替代,它只在失焦时触发,无法及时更新 UI - 若用框架(如 React/Vue),确保 ref 绑定正确,并在
useEffect或mounted中补 dispatch
最易被忽略的是:所有 transition 必须显式声明,不能只写 transition: all .2s——它会让 width/height 等无关属性也参与动画,造成渲染抖动。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











