[aria-invalid="true"]等选择器仅控制样式,无法让屏幕阅读器感知错误,必须配合aria-describedby和正确id绑定才能触发播报;aria-disabled不阻止焦点,需手动处理;[role="alertdialog"]仅响应语义,不定义语义;避免用aria覆盖原生可访问性。

[aria-invalid="true"] 这类选择器能直接驱动样式,但仅靠它无法让屏幕阅读器感知错误——必须配合 aria-describedby 和真实 DOM 结构,否则只是“视觉上红了,读屏器完全不知道发生了什么”。
为什么[aria-invalid]选择器本身不解决无障碍问题
它只负责样式响应,不参与语义传递。浏览器和读屏器不会因为 CSS 里写了 [aria-invalid="true"] 就自动播报错误。真正触发播报的是:aria-invalid="true" 属性值 + 与 aria-describedby 指向的错误文案 ID 的显式绑定。
- 仅加
[aria-invalid="true"] { border-color: #e53e3e; }:键盘用户看到红框,但视障用户毫无提示 - 漏掉
aria-describedby="error-username":即使有错误文案元素,读屏器也找不到它 - 错误文案元素没设
id="error-username":aria-describedby指向失效,等于没写
[aria-disabled="true"] 不能替代原生 disabled
自定义按钮(如 <div role="button" aria-disabled="true">)用该选择器可控制灰态样式,但存在硬伤:
<ul>
<li>
<code>aria-disabled 不阻止焦点进入,Tab 仍能停在它上面,Enter/Space 也不会默认触发——必须手动监听 keydown 并过滤
<button disabled></button> 自带 :disabled 伪类、自动失焦、键盘拦截,更可靠aria-disabled,务必同步设 tabindex="-1" 防止意外聚焦用[role="alertdialog"]区分模态框语义,但别滥用
这个选择器可用于统一设置警告类弹窗的遮罩层样式或关闭逻辑,但它不是“让弹窗变警告”的开关——角色语义由 HTML 中的 role 属性决定,CSS 只是响应。
-
[role="alertdialog"] .modal-backdrop可设pointer-events: none,强制用户必须操作按钮而非点背景关闭 - 但若 HTML 里写的是
role="dialog",该选择器完全不匹配,样式不会生效 - 不要用它“伪装”警告行为:真正的
alertdialog必须禁用外部点击、自动聚焦首可操作项、Esc 键不可关闭
避免[aria-*]选择器覆盖原生可访问性
例如给 <input type="checkbox"> 加 [aria-checked="true"] 并用 CSS 隐藏原生控件再重绘,风险很高:
- 部分读屏器(尤其旧版 NVDA)可能忽略
aria-checked,只读原生checked属性 - 若 JS 渲染失败或属性未同步,视觉状态和实际状态会不一致
- 更稳妥的做法:保留原生
input,用input:checked + label::before控制外观,aria-属性仅作补充
真正关键的不是“怎么用 CSS 选中 ARIA 属性”,而是确保每个 aria- 属性都对应一个被读屏器识别的语义动作——样式只是副产品,别让它喧宾夺主。











