真正隐藏又可读应使用.sr-only类:绝对定位+1px宽高+负边距+溢出隐藏+clip/clip-path+white-space:nowrap;禁用display:none、visibility:hidden、hidden属性。

screen reader only 类名怎么写才真正隐藏又可读
用 display: none 或 visibility: hidden 会同时屏蔽视觉和屏幕阅读器,必须用仅视觉隐藏、保留语义的 CSS 方式。
推荐使用以下标准写法(WCAG 兼容):
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
- 不能省略
clip或clip-path(旧版 IE 需clip,现代浏览器建议补clip-path: inset(50%)) -
white-space: nowrap防止长文本换行后意外撑开尺寸 - 不要用
font-size: 0或color: transparent,部分阅读器会跳过
aria-label 和 aria-labelledby 哪个该用
二者都让屏幕阅读器读出提示,但触发逻辑完全不同,选错会导致重复播报或静默。
-
aria-label:直接提供替代文本,适合无可见标签的控件(如纯图标按钮)
→<button aria-label="删除此项"><i class="icon-trash"></i></button> -
aria-labelledby:引用页面中**已存在的、可见的文本元素 ID**,适合已有标题/说明的场景
→<h2 id="search-title">站内搜索</h2> <input aria-labelledby="search-title" type="search"> - 避免同时用
aria-label和aria-labelledby,后者优先级更高,前者会被忽略
为什么用了 sr-only 还被 NVDA 读两次
常见于表单控件 + 隐藏提示组合,本质是标签绑定失效或冗余语义叠加。
- 检查是否误给
<input>同时加了aria-label和包裹sr-only的<label></label>—— 两者都会被读,只留其一 - 确认
sr-only元素没被意外放进<button></button>或<a></a>内部(某些阅读器会把内部文本当作按钮名称重复播报) - 动态插入的
sr-only文本需配合aria-live="polite"才能被监听到,否则静默
HTML5 hidden 属性能不能替代 sr-only
不能。hidden 是全局隐藏属性,对屏幕阅读器也生效,等价于 display: none。
它只适合「当前完全不需要任何用户访问的内容」,比如未激活的 Tab 面板、加载中的占位文案。
-
<div hidden>暂无数据</div>→ 屏幕阅读器完全不读 -
<div class="sr-only">暂无数据</div>→ 视觉不可见,但阅读器可读 - 别混用:
<div hidden class="sr-only"> 是自相矛盾的写法 实际项目里最容易漏的是动态内容的可访问性同步——比如错误提示用 JS 插入 <code>sr-only文本,却忘了加aria-live,或者表单校验后只改了颜色没更新aria-invalid状态。这些细节不报错,但会让依赖阅读器的用户卡在无声的界面上。











