:read-only伪类仅对显式含readonly属性的input(非hidden)和textarea生效,disabled、contenteditable="false"或js赋值el.readonly=true均无效;select等元素完全不支持;推荐优先使用[readonly]属性选择器,并注意vue用:readonly、react用readonly确保dom渲染。

为什么:read-only样式经常不生效
根本原因不是选择器写错,而是元素压根没进入:read-only状态。浏览器只对显式带有readonly HTML 属性的<input>(非type="hidden")和<textarea></textarea>匹配该伪类——disabled不算,contenteditable="false"不算,JS 赋值el.readOnly = true也不算(除非同步调用el.setAttribute('readonly', ''))。<select></select>、<button></button>、<div>等完全不支持,加了属性也白搭。<h3>
<code>[readonly]比:read-only更稳妥
直接用属性选择器,兼容性好、行为确定,IE11 都能跑:
input[readonly], textarea[readonly] {
background-color: #f5f5f5;
color: #666;
border-color: #ddd;
cursor: not-allowed;
}
注意三点:
- 必须写
[readonly],不是[readonly="true"]或[readonly=""]——HTML 布尔属性有即生效 - 别漏掉
textarea,它同样支持readonly且常被忽略 - 加上
cursor: not-allowed比单改背景色更能直观传达“不可编辑”意图
:read-only和:disabled共存时样式被覆盖
如果一个输入框同时带readonly和disabled属性,:disabled规则一定生效,:read-only完全被忽略——这不是优先级问题,是浏览器语义判定结果:disabled字段既不提交、也不聚焦,readonly字段则相反。业务上二者不该共存:
- 要用户能复制内容(如订单号),用
readonly+:read-only或[readonly] - 要彻底锁死交互(如审批流程中已归档字段),用
disabled+:disabled - 别混用,否则样式和语义都混乱
Safari 和旧版 Edge 的兼容性陷阱
:read-only在 Safari 中从 iOS 15.4 / macOS 12.3 才稳定支持,旧版直接忽略;IE 全系不识别。所以生产环境必须降级:
/* ✅ 双保险写法 */
input[readonly], textarea[readonly] {
background-color: #f5f5f5;
}
input:read-only, textarea:read-only {
background-color: #f5f5f5;
}
Vue/React 中还要确认框架是否真把readonly属性渲染到了 DOM 上:Vue 用:readonly="isReadonly",React 用readOnly={true}(注意大小写),否则[readonly]也匹配不到。











