:disabled伪类仅对原生表单控件生效,不适用于div等非表单元素;禁用元素不可聚焦,:disabled:focus不可靠;需手动设置cursor: not-allowed和可访问性样式。

disabled 伪类只能作用于表单控件元素
:disabled 伪类不是万能的,它只对原生可禁用的表单元素生效,比如 <button></button>、<input>(含 type="text"、"checkbox"、"radio" 等)、<select></select>、<textarea></textarea>。对 <div>、<code><span></span> 或自定义组件加 disabled 属性,:disabled 完全不会匹配。
常见错误是给一个 <div class="btn">提交</div> 加了 disabled 属性,再写 div:disabled { opacity: 0.5; } —— 这条规则根本不会触发,浏览器直接忽略。
- 必须用语义化表单控件,不能靠 div 模拟按钮后指望
:disabled生效 - 若必须用非表单元素模拟禁用态,得手动加类名(如
.is-disabled),再用类选择器控制样式 -
contenteditable元素即使设disabled,也不受:disabled影响
disabled 元素默认不可聚焦,但 focus 样式仍可能残留
被 disabled 的 <button></button> 或 <input> 无法获得焦点,所以 :focus 不会触发。但如果你写了 button:disabled:focus { ... },虽然语法合法,实际永远不会应用——因为 disabled 元素跳过焦点流程。
真正容易出问题的是:用户点击禁用按钮前,该按钮刚处于可聚焦状态,且已有 :focus 样式;禁用后 DOM 状态变了,但焦点未移走,视觉上仍保留 focus 样式(尤其在 Safari 和旧版 Chrome 中较明显)。
立即学习“前端免费学习笔记(深入)”;
- 禁用操作后,显式调用
element.blur()可清除残留焦点样式 - 更稳妥的做法是把
:focus和:disabled样式分开定义,避免叠加冲突 - 不要依赖
:disabled:focus做视觉反馈,它不可靠
disabled 样式优先级低,容易被其他规则覆盖
:disabled 本身没有特殊权重,它的优先级完全取决于选择器整体特异性。例如 button:disabled 的特异性是 0,1,1(一个标签 + 一个伪类),而 .form-control button 是 0,1,1,两者相等,后声明者胜出。
这就导致常见现象:全局定义了 button { background: blue; },又写了 button:disabled { background: grey; },但某个按钮因父容器类名多了一层,被 .modal-footer button 覆盖,结果禁用后还是蓝色。
- 提高特异性:用
button:disabled, input:disabled, select:disabled组合写,或加!important(仅限小范围兜底) - 推荐在 CSS 初始化层统一重置所有禁用态,比如 Bootstrap 的
.btn:disabled就带足够特异性 - 注意伪类顺序:
:hover:disabled无效,应写成:disabled:hover(尽管 hover 不会触发,但语法上后者才被识别)
disabled 状态不触发 pointer-events,但 cursor 仍需手动设置
浏览器对 disabled 元素自动设置 pointer-events: none,所以鼠标事件(click、hover)不会冒泡或触发。但这不意味着光标样式会自动变成 not-allowed —— 默认仍是 default 或继承父级 cursor。
用户看到一个灰色按钮却显示手型光标,会产生“点一下试试”的错觉,反而降低表单体验。
- 务必显式声明
button:disabled { cursor: not-allowed; } - 对
<input type="checkbox">等,禁用后也建议加cursor: not-allowed,否则用户可能反复点击未响应的复选框 - 避免用
cursor: default覆盖,它和not-allowed视觉区分度不够
禁用态样式最常被忽视的,其实是与颜色对比度相关的可访问性问题。系统禁用色(如 #aaa)在浅灰背景上可能低于 WCAG AA 标准,需要单独校验 contrast ratio;另外,仅靠颜色变化提示禁用状态对色觉障碍用户不友好,最好配合图标、文字提示或透明度+边框变化组合使用。










