当目标是彻底禁用交互、阻止表单提交且禁止聚焦时,必须用 :disabled;它匹配 disabled 属性,灰化样式、移除焦点、跳过序列化;而 :read-only 仅基于运行时可编辑性判断,兼容性差且不阻断交互或提交。

什么时候该用 :disabled,而不是 :read-only
当目标是「彻底禁用交互 + 阻止表单提交 + 禁止聚焦」时,必须用 :disabled。它匹配所有带 disabled 属性的表单控件(input、button、select、textarea、checkbox 等),且浏览器会统一应用禁用语义:灰化外观、移除焦点能力、跳过表单序列化。
常见误用:input[type="button"] 加 readonly 想让它变灰不可点——无效,按钮根本不响应 readonly,必须用 disabled 才能生效。
关键区别点:
-
:disabled匹配的是 HTMLdisabled属性存在且为真值(如disabled或disabled="disabled") - 样式权重相同情况下,
:disabled声明会覆盖:read-only(哪怕后者写在后面) -
disabled元素无法触发focus、click、input等事件,JS 也拿不到其值(formdata.get()不包含它)
:read-only 实际匹配哪些元素?
:read-only 不是 readonly 属性的 CSS 映射,而是基于「内容是否可编辑」的运行时判断。它只匹配满足以下全部条件的元素:
立即学习“前端免费学习笔记(深入)”;
- 原生表单控件(
input[type="text"]、input[type="password"]、input[type="number"]、textarea) - 未设置
contenteditable属性 - 未设置
disabled属性 - 内容实际不可由用户修改(即有
readonly属性,或被其他机制锁定)
典型不匹配场景:
-
<input type="hidden" readonly>——type="hidden"本就不允许编辑,但浏览器不认为它属于:read-only范畴 -
<textarea disabled></textarea>—— 它走:disabled,不是:read-only <div contenteditable="false"> —— 虽然不可编辑,但它是非表单元素,<code>:read-only在多数浏览器中不匹配(仅部分支持)为什么推荐用
[readonly]而不是:read-only写样式?因为
:read-only兼容性差(Safari 直到 iOS 15.4 才完整支持,旧版 Edge 完全不支持),且匹配逻辑模糊,容易出现「加了readonly但样式没生效」的情况。更可靠的做法是直接使用属性选择器
[readonly]:-
[readonly]行为确定:只要 HTML 中写了readonly(无论值是空字符串还是"readonly"),就匹配 - 兼容性好:IE7+ 全支持
- 可配合其他属性组合,比如
input[readonly][type="text"]精准控制文本框 - 避免和
:disabled的样式冲突问题([readonly]权重与:disabled相同,按声明顺序覆盖)
示例:
input[readonly] { background-color: #f5f5f5; color: #666; cursor: default; }同时设
readonly和disabled会发生什么?语法上允许,但语义冲突,应避免。行为表现取决于浏览器实现,但通常:
- DOM 上两个属性都存在,
element.readOnly === true,element.disabled === true - CSS 中
:disabled会生效,:read-only可能被忽略(因disabled已使元素不可编辑) - 表单提交时,该字段值不会被包含(
disabled优先级更高) - JS 修改
value仍可行,但用户无法操作
真正需要「视觉只读 + 提交值」时,只用
readonly;需要「彻底禁用 + 不提交」时,只用disabled。混用往往是逻辑混乱的信号,后续容易在 JS 里补一堆preventDefault或tabindex="-1"来掩盖问题。最常被忽略的一点:
:read-only是纯视觉提示,它不阻止 focus、不阻止键盘输入拦截失败后的意外修改、也不影响表单逻辑——如果你靠它来“防止用户改值”,那就得立刻补 JS 校验和 submit 拦截。-


















