:read-only仅是样式钩子,不防修改;真正防改靠html readonly属性。它只匹配含该布尔属性的文本类input(如text、email)和textarea,不支持select、button、contenteditable等;js赋值el.readonly=true无效,须setattribute('readonly', '');ie全系不支持,需用[readonly]兜底。

:read-only 不能防止输入框被修改,它只是个样式钩子。真正防止修改靠的是 HTML 的 readonly 属性;CSS 只负责“告诉用户:这东西不能改”。
:read-only 生效的前提是元素真有 readonly 属性
浏览器只对以下两类元素响应 :read-only:
-
<input type="text">、<input type="email">、<input type="number">等文本类输入框 <textarea></textarea>
不支持的包括:<select></select>、<button></button>、<div contenteditable="false">、自定义组件,哪怕你手动加了 <code>readonly 属性也没用。
常见错误:
- 用 JS 设置
el.readOnly = true,但没调用el.setAttribute('readonly', '')→ DevTools 里看不到readonly字样,样式就不触发 - 把
disabled当readonly用 →:disabled和:read-only完全不重叠,样式不会生效 - 在
<input type="checkbox">上加readonly→ 浏览器忽略该属性,:read-only不匹配
验证方法:打开浏览器开发者工具,检查 Elements 面板,确认 readonly 是作为布尔属性真实出现在标签上,而不是仅存在于 JS 对象中。
灰色背景别用 opacity 或 filter: grayscale()
这两种写法会连带影响文字可读性、边框清晰度,甚至干扰父容器的渲染行为(比如在 Safari 中触发重绘异常)。
推荐组合:
-
background-color: #f5f5f5;(浅灰底,不压字) -
color: #666;(文字稍降权,但保持清晰) -
border-color: #ddd;(保留结构感,避免和:disabled混淆) -
cursor: default;(鼠标悬停不是 I 型光标,直观提示不可编辑) - 可选:
user-select: text;(允许复制内容,符合只读场景的真实需求)
如果背景是图片或渐变,可用 background-blend-mode: multiply; 叠一层 linear-gradient(rgba(245, 245, 245, 0.8), rgba(245, 245, 245, 0.8)),但需测试兼容性(IE/旧 Edge 不支持)。
IE 和旧版 Edge 必须用 [readonly] 兜底
:read-only 在 IE 全系中完全不识别;Edge ≤17 也有兼容问题。不能只写:
input:read-only { background-color: #f5f5f5; }
得补一句:
input[readonly] { background-color: #f5f5f5; }
注意:input[readonly] 是属性选择器,只要 HTML 里写了 readonly 就匹配,不管 JS 是否改过状态;而 :read-only 是伪类,随 DOM 状态实时变化。两者优先级不同,:read-only 更高,但 IE 里它根本不存在。
Vue/React 中要确保最终渲染出的 DOM 确实含 readonly 字样,比如 Vue 用 v-bind:readonly="true",React 用 readOnly={true},别漏掉大小写。
:read-only 不阻止聚焦、不阻止右键、不阻止复制粘贴。如果你需要禁用这些交互,得额外加 tabindex="-1"(跳过 Tab 键)、oncontextmenu="return false;"(禁右键)或 user-select: none;(禁文本选择)——但请想清楚:只读 ≠ 禁用,用户常需复制订单号、手机号等字段,一刀切反而损害体验。











