:read-write仅匹配三类原生可编辑元素:input(排除hidden/radio/checkbox/file)、textarea、select(Safari支持弱);不匹配contenteditable元素、range/color输入框、button等;匹配仅依赖HTML属性存在与否,与JS状态无关。
:read-write 不是“所有看起来能点能输的都算”,它只认三类原生可编辑元素:<input>(排除 type="hidden"、"radio"、"checkbox"、"file" 等不可文本输入类型)、<textarea>、<select>。注意:<select> 在部分浏览器中行为不一致,Chrome 和 Firefox 通常支持,Safari 对其 :read-write 匹配较弱。
常见误判:
div[contenteditable="true"] 默认不匹配 :read-write —— 即使聚焦了也不自动触发,除非你手动加 :focus
input[type="range"] 或 input[type="color"] 虽可交互,但不接受文本输入,多数浏览器不视为 :read-write
button、output、自定义 Web Component 即使绑了事件或 JS 控制,也完全不在 :read-write 的作用域内它只看 HTML 属性是否存在,不响应 JavaScript 动态修改的逻辑状态。比如:
<input readonly> → 不匹配 :read-write(布尔属性写法,无值即生效)<input readonly="false"> → 依然匹配 :read-only,因为 readonly 属性存在,值真假无关element.readOnly = false(JS 设置)→ 样式会更新,但前提是该属性原本就存在;如果 DOM 里根本没写 readonly,JS 设 true 再设 false 才会触发切换oninput="return false" 或 event.preventDefault() → 完全不影响 :read-write 匹配,伪类根本不读这些三者语义不同,但渲染时有明确权重顺序::disabled >:read-only >:read-write。这意味着:
input 同时有 disabled 和 readonly 属性,:disabled 样式一定生效,:read-only 和 :read-write 都被覆盖:read-only 和 :read-write 是互斥的,但不是穷尽覆盖:比如 input[type="hidden"] 既不匹配 :read-write 也不匹配 :read-only,它什么伪类都不进:read-write “撤销” :read-only 的背景色——两个伪类应各自完整定义,而不是靠层叠覆盖想给用户明确反馈“现在可以编辑”,:read-write:focus 看似合理,但问题不少:
:read-write,旧版直接失效:read-write 本身不带交互反馈(比如 hover、active),仅反映静态可写性:focus 更通用、兼容性更好推荐写法:
input:not([readonly]):not([disabled]):focus,
textarea:not([readonly]):not([disabled]):focus {
border-width: 2px;
}
[contenteditable="true"]:focus {
border: 2px solid #007bff;
outline: none;
}
如果你必须区分“可编辑但未聚焦”和“已聚焦”,纯 CSS 无法靠 :read-write 实现——它不响应鼠标悬停,也不反映初始渲染前的状态变化,得靠 class 切换或 JS 监听。