:read-write仅匹配真正可编辑的原生表单控件(如text/email/number型input、textarea)和contenteditable="true"元素,需同时满足无readonly、无disabled且类型支持输入,不响应js禁用逻辑。

:read-write 只匹配真正可编辑的原生表单控件和 contenteditable="true" 元素,不是所有“没加 readonly”的元素都算数,更不响应 JS 控制的禁用逻辑。
哪些元素实际触发 :read-write?
浏览器只对特定元素类型启用该伪类,且依赖真实可编辑能力,而非属性存在与否:
-
<input>(仅type="text"、type="email"、type="number"等支持文本输入的类型;type="radio"、type="hidden"、type="file"不匹配) -
<textarea></textarea>(始终匹配,除非带readonly或disabled) -
<select></select>(部分浏览器支持,但规范未强制,Chrome/Firefox 通常不匹配,Safari 更不稳定) -
div[contenteditable="true"](需显式设置属性值为"true",contenteditable无值或"false"均不匹配) -
button、span、div(即使加了readonly属性也完全无效)
:read-write 和 input:not([readonly]) 本质不同
两者语义和行为差异直接影响样式是否生效:
-
input:not([readonly])是纯属性筛选器:只要 HTML 中没写readonly,哪怕el.disabled = true或el.readOnly = true,它仍会匹配 -
input:read-write是 UA 状态判定:必须同时满足「未设readonly」+「未设disabled」+「类型本身支持输入」,三者缺一不可 -
<input type="number" readonly>→ 不匹配:read-write,也不匹配:read-only(因 Safari ≤15.3 存在漏匹配 bug) -
<input disabled>→ 既不匹配:read-write,也不匹配:read-only,只走:disabled
contenteditable 元素不能直接靠 :read-write 触发样式
这是最常踩的坑:给 div[contenteditable="true"] 写 div:read-write 在多数浏览器中根本不会生效。
- 原因:规范允许但浏览器实现保守,
:read-write对非表单元素默认不激活,除非该元素当前获得焦点 - 正确做法是组合使用:
div[contenteditable="true"]:focus或[contenteditable="true"]:focus-within - 若需区分“可编辑但未聚焦”状态,CSS 无解——
:read-write不响应 hover 或初始渲染态,必须靠 class 切换或 JS 监听contenteditable属性变更 - 注意
contenteditable="false"的元素不匹配:read-only,应改用属性选择器:[contenteditable="false"]
兼容性与 fallback 方案必须提前考虑
IE 全系不支持 :read-write,且 Safari 对 input[type="number"] 的支持直到 iOS 15.4 才稳定。
- 安全写法优先用属性组合:
input:not([readonly]):not([disabled])+textarea:not([readonly]):not([disabled]) - 对
contenteditable区域,统一用[contenteditable="true"]代替伪类,避免兼容断层 - 若必须用伪类,建议加降级规则:
input:read-write, input:not([readonly]):not([disabled]),让老浏览器回退到属性选择器 -
:read-write:focus在 Safari 上有兼容风险,更稳的是input:not([readonly]):not([disabled]):focus
真正难的不是写对选择器,而是理解浏览器到底“认什么”:它只看 DOM 属性和内置可编辑性,不关心你的 JS 锁没锁、事件拦没拦。一旦混淆了“HTML 声明”和“运行时状态”,样式就必然失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











