button:disabled鼠标仍为手型或箭头,因该伪类仅禁用交互逻辑,不自动修改光标;必须显式声明cursor: not-allowed,且需同时使用button:disabled和button[disabled]覆盖动态与静态禁用场景。

button:disabled 为什么鼠标还是手型或默认箭头
因为 :disabled 本身不改光标,浏览器只禁交互逻辑(点不动、不聚焦),但 cursor 仍沿用元素默认值:原生 button 是 default,a 是 pointer。不手动设,就永远不是 not-allowed。
必须同时写 button:disabled 和 button[disabled]
只靠 button:disabled 会漏掉服务端渲染(SSR)生成的静态按钮;只靠 button[disabled] 会漏掉 JS 动态设置 el.disabled = true 的情况(React/Vue 默认行为)。两者覆盖场景不同,缺一不可:
-
button:disabled匹配“当前是否被禁用”的运行时状态 -
button[disabled]匹配“HTML 中是否写了disabled属性”的静态结构 - 框架里用
:disabled="isLoading"或disabled={isLoading},只触发前者;SSR 输出的<button disabled></button>只响应后者
cursor: not-allowed 生效但鼠标“穿”过按钮?
常见于加了 pointer-events: none 后又想显示 not-allowed 光标——这不可能。因为 pointer-events: none 会让元素彻底退出鼠标事件流,连 hover 都不会触发,自然无法应用 cursor 样式。正确做法是:
- 保留
pointer-events: auto(或直接不写,这是默认值) - 确保没有更高优先级规则覆盖,比如
button { cursor: pointer; }会压过button:disabled - 若按钮内有图标等子元素,加
button[disabled] * { cursor: not-allowed; }防止继承污染 - 旧版 Safari 对
:disabled的 cursor 支持弱,必要时加!important
非 button 元素(如 div、自定义组件)怎么办
:disabled 只对原生可禁用表单控件有效:button、input、select、textarea。给 div 加 disabled 属性完全无效,CSS 不识别,JS 也不阻止事件。
正确路径只有两条:
- 换回语义化
<button type="button"></button>,别模拟按钮 - 若必须用自定义组件,用 class 控制状态:
<my-button class="is-disabled"></my-button>,再配.is-disabled { cursor: not-allowed; },同步设aria-disabled="true"和tabindex="-1"
任何绕过原生 disabled 属性的方案,都会在键盘导航、屏幕阅读器、表单提交链路中出问题——光标只是表层信号,背后的状态同步才是关键。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











