根本原因是浏览器只对原生表单控件(button、input等)识别disabled属性,自定义组件需确保disabled真实透传至原生标签,且注意Shadow DOM隔离、iOS Safari兼容性及aria-disabled语义一致性。

button:disabled 不匹配自定义组件
根本原因不是 CSS 写错了,而是浏览器根本不识别你的 框架组件常把 iOS Safari(尤其旧版本)对
真正麻烦的点从来不在怎么写那几行 CSS,而在于你是否确认过:DOM 属性真存在、框架透传到位、Shadow DOM 是否隔离、移动端是否 fallback 到 或 :disabled 伪类只对原生表单控件生效:、、、、。你在自定义标签上加 disabled 属性,DOM 层面存在,但 CSS 引擎直接忽略该伪类匹配。React/Vue 中 disabled 属性没透传到原生标签
disabled 当作 prop 接收,但默认不渲染到最终 DOM 的 上。结果是:JS 状态变了,UI 看起来“应该禁用”,但真实 DOM 里 标签根本没有 disabled 属性,button:disabled 自然不触发。
disabled 最终落到 ,而不是只挂在 wrapper div 上,别漏掉冒号;若用封装组件,需显式透传:v-bind="$attrs"(2.x)或 v-bind="$$attrs"(3.x)disabled 属性是否真实出现在 标签上——不是父容器,不是自定义标签,必须是原生可禁用标签用了
[disabled] 却仍不生效[disabled] 属性选择器比 :disabled 更宽泛,但它也有前提:属性必须真实存在于 DOM 节点上。常见失效场景包括:
el.disabled = true,这会更新 IDL 属性但**不自动添加 HTML 属性**;需配 el.toggleAttribute('disabled', true) 或 el.setAttribute('disabled', '')
:disabled="isSubmitting ? 'disabled' : null" → 渲染出 disabled="disabled" 是合法的,但 disabled="false" 依然触发禁用(因为属性存在即禁用),且 [disabled] 仍会匹配——但语义错误[disabled] 规则必须写在 shadow root 内部移动端 iOS Safari 对 :disabled 支持弱
button:disabled 的样式应用极不稳定:opacity 可能被忽略、background-color 不生效、甚至 cursor 保持手型。这不是你 CSS 写得不够全,而是引擎层面支持缺失。
pointer-events: none 做行为兜底,但注意它会同时禁用 focus 和键盘导航color、background-color、border-color)都得显式声明filter: grayscale() —— iOS Safari 渲染异常,高对比度模式下失效,屏幕阅读器可能误判状态aria-disabled="true" + 类名控制样式,并同步处理键盘焦点逻辑pointer-events、以及 aria-disabled 与原生 disabled 是否混用冲突。漏掉任意一环,用户就会遇到“看着灰了,点一下却提交了”这种事。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











