.sr-only是bootstrap中专为屏幕阅读器设计的辅助类,通过绝对定位、尺寸归零和溢出裁剪实现视觉隐藏但保留可访问性,用于增强无障碍支持。

Bootstrap 本身不是无障碍(a11y)的银弹,但也不是障碍本身——它提供基础支持,关键在你怎么用。
Bootstrap 内置 ARIA 属性是否够用?
不够。比如 button 元素自带语义和键盘可聚焦能力,但如果你用 <div class="btn">提交</div> + onclick 模拟按钮,屏幕阅读器根本不会把它当按钮读;同样,dropdown 组件默认加了 aria-expanded 和 role="menu",但若你用 JS 动态切换下拉状态却没同步更新 aria-expanded 值,辅助技术就会“失联”。
常见错误现象:
- 轮播图(
carousel)只靠aria-live="polite",没加aria-current="true"标记当前项,屏幕阅读器不播报“第2张,共5张” - 模态框(
modal)没设aria-modal="true"或缺失aria-labelledby,焦点管理失效,键盘用户卡死在背景内容里 - 自定义表单控件(如开关、滑块)用
bootstrap-switch插件,但没补role="switch"和aria-checked,状态变化完全不可感知
Bootstrap 5.3 的 screenreader-only 类怎么用?
.visually-hidden(5.3+ 推荐)和旧版 .sr-only 都是让元素视觉隐藏但保留在辅助技术树中,但二者行为有细微差别:
-
.visually-hidden使用clip-path: inset(50%)+position: absolute,兼容性更好,且不会被某些旧版 JAWS 错误忽略 -
.sr-only依赖clip(已废弃 CSS 属性),在 Safari 15.4+ 和部分 Edge 版本中可能失效 - 不能直接套在交互控件上:比如给
<input type="checkbox">加.visually-hidden后,必须额外提供一个带for属性的<label></label>,否则屏幕阅读器无法关联描述文本
示例正确写法:
<input type="checkbox" id="newsletter" class="visually-hidden"><label for="newsletter">订阅邮件通知</label>
哪些 Bootstrap 组件最容易出无障碍问题?
不是所有组件都“开箱即用”,尤其当脱离默认 HTML 结构或配合 JS 扩展时:
-
accordion:每个button必须有aria-controls指向对应div.collapse的 ID;折叠面板本身需加aria-labelledby回指触发按钮 -
nav-tabs:整个导航容器要加role="tablist",每个 tab 按钮加role="tab"和aria-selected,面板加role="tabpanel"并与 tab 关联 -
tooltip/popover:默认不带role,需手动加role="tooltip"或role="dialog";触发元素必须有aria-describedby指向提示内容 ID - 颜色对比度:Bootstrap 默认配色(如
.text-muted在浅灰背景上)常低于 WCAG 要求的 4.5:1,需用工具(如 Accessibility Insights)实测
为什么改完 ARIA 还被屏幕阅读器跳过?
最常被忽略的是 DOM 更新时机和焦点流控制:
- 动态插入内容(如 AJAX 加载表格行)后,仅加
aria-live不够,还得确保插入点本身有role="region"或role="log",否则某些阅读器不监听 - 模态框打开后,焦点没强制移到第一个可聚焦元素(如
modal-header内的关闭按钮或标题),键盘用户会从页面顶部开始 Tab,体验断裂 - 用
display: none或visibility: hidden隐藏内容时,aria-hidden="true"必须同步设置,否则隐藏区域仍可能被读出 - 自定义事件(如右键菜单、长按弹窗)缺乏键盘等效操作(如 Shift+F10),等于对屏幕阅读器用户彻底关闭入口
复杂点不在属性名写错,而在于状态同步、焦点链完整、DOM 生命周期与 ARIA 更新严格对齐——这三者漏掉任一环,无障碍就断在真实用户手里。











