:read-only伪类仅匹配显式设置readonly属性的input/textarea,不控制行为;样式失效主因是DOM无readonly属性、元素类型不支持或浏览器兼容问题。

:read-only 伪类不能禁止用户修改输入框——它只响应已存在的 readonly 属性,本身不控制行为。真正起“禁止修改”作用的是 HTML 的 readonly 属性,:read-only 只负责给它加样式。
为什么 :read-only 样式没生效?检查这三件事
常见现象:写了 input:read-only { background: #eee; },但输入框看起来和普通的一样。
- DOM 中根本没有
readonly属性:必须是<input readonly>或el.setAttribute('readonly', ''),仅 JS 赋值el.readOnly = true不触发伪类 - 元素类型不对:
:read-only只匹配<input type="text">、<input type="email">、<input type="number">和<textarea>;<select>、<button>、<input type="checkbox">加了也无效 - 浏览器兼容性问题:旧版 Safari(iOS 15.3 及更早)和部分 Android WebView 对
type="number"的:read-only支持不全,建议改用type="text"+inputmode="numeric"+ JS 拦截
:read-only 和 :disabled 别混着用
两者语义冲突,视觉和行为都不同:
-
input:read-only元素仍可聚焦、可选中、可右键粘贴、值会随表单提交 -
input:disabled元素失焦、不可交互、灰色置灰、值不提交 - 如果一个
<input readonly disabled>同时存在两个属性,:disabled样式一定覆盖:read-only,哪怕你把它写在后面 - 想统一视觉?显式写成
input:read-only, input:disabled,但 JS 逻辑里仍要区分:表单校验需知道是“保留提交”还是“彻底排除”
动态切换只读状态时,CSS 不更新?其实是 DOM 没同步
Vue/React 中常见问题:状态变了,但样式没变。
立即学习“前端免费学习笔记(深入)”;
- Vue 模板中写
<input :readonly="isReadonly">是对的,但若isReadonly是false,Vue 会移除readonly属性,此时:read-only自然失效 - React 中必须用
readOnly={isReadonly}(注意驼峰),拼成readonly就不会渲染属性 - 原生 JS 切换时,设只读用
el.setAttribute('readonly', ''),解除用el.removeAttribute('readonly');别依赖el.readOnly = false,Safari 15 及更早版本不认 - DevTools 里直接看 Elements 面板,确认
readonly字样是否真实出现在标签上——这是唯一判断依据
真正容易被忽略的是::read-only 只是样式钩子,不是安全机制。用户删掉属性、粘贴内容、甚至控制台改 value,浏览器都照收照发。后端必须校验字段是否被篡改,前端样式只是体验提示。


















