html无障碍本身支持屏幕阅读器,问题在于语义缺失、aria误用或交互逻辑未同步;div/span默认无语义需补role/tabindex/aria属性;表单label须显式关联控件;自定义组件需透传状态属性并管理焦点。

HTML 无障碍本身是支持屏幕阅读器的,问题通常出在语义缺失、ARIA 使用不当或交互逻辑未同步——不是“不支持”,而是没写对。
为什么 div 和 span 读不出来?
屏幕阅读器依赖语义化标签和角色(role)识别内容类型。div 和 span 默认无语义,即使加了文字也不会被识别为可读内容块,更不会触发自动朗读。
- 把按钮逻辑写在
div上?必须加role="button"+tabindex="0"+aria-pressed(如需状态反馈) - 用
span做图标?加上aria-hidden="true"防止冗余播报;若图标含信息(如“警告”),改用svg+<title></title>或aria-label - 列表、表格、导航等结构,优先用
ul/ol、table、nav,而非嵌套div
aria-label 和 aria-labelledby 用哪个?
二者都用于提供可访问的文本描述,但触发时机和维护成本不同:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
-
aria-label:适合静态、简短说明(如按钮“搜索”),值直接写死,无法复用,也不支持 HTML 内容 -
aria-labelledby:指向页面中已有元素的id,适合动态或复用场景(如模态框标题关联到h2 id="modal-title"),且支持多 ID 引用(空格分隔) - 别混用:
aria-label和aria-labelledby同时存在时,aria-label会覆盖后者 - 慎用
aria-describedby:它只补充说明,不替代主名称,屏幕阅读器通常在主名后延迟播报,不适合关键标识
表单控件为什么没读出 label?
没读出来,大概率是 label 和控件没建立正确关联——不是加了文字就行,必须有显式绑定。
- 推荐写法:
<label for="email">邮箱地址</label><input id="email" type="email">(for必须严格匹配id) - 嵌套写法也有效:
<label>邮箱地址<input type="email"></label>,但注意内部不能有其他块级元素(如div)打断流式结构 - 避免仅靠视觉位置“看起来像 label”:CSS 隐藏
label却不加aria-label,会导致完全不可读 - 自定义组件(如开关、多选标签)必须手动透传
aria-checked、aria-multiselectable等状态属性
最常被忽略的是焦点管理:弹窗打开后焦点没移到首交互元素,关闭后没回退到触发点。这会让屏幕阅读器用户彻底迷失上下文——语义再准,操作链断了也没用。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










