svg图标必须加role="img"和aria-label,否则屏幕阅读器默认跳过或仅读“图形”,无法传达“关闭”“搜索”等操作意图;正确做法是用role="img"声明图像语义,aria-label提供动词短语描述操作结果,并确保外层容器具备可聚焦和交互能力。

SVG图标必须加role="img"和aria-label
内联SVG本身没有语义,屏幕阅读器默认跳过或只读“图形”,不加显式声明就等于对视障用户“隐藏”了按钮功能。单纯靠CSS显示图标、靠视觉位置暗示用途,键盘用户和屏幕阅读器都无从得知这是“关闭”“搜索”还是“设置”。
正确做法是:role="img"告诉辅助技术这是图像类内容,aria-label提供可读的意图描述:
<svg role="img" aria-label="删除此项目" viewbox="0 0 24 24"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"></path></svg>
-
aria-label值必须是动词短语,说明操作结果(如“删除此项目”),不是名词(如“垃圾桶图标”) - 避免用
title替代aria-label——title只在悬停时触发,且多数屏幕阅读器默认不读 - 若SVG作为链接或按钮的子元素,外层容器仍需
role="button"和tabindex="0",否则键盘无法聚焦
font-icon类图标要补aria-hidden="true"并配显式文本
用@font-face或图标字体(如Font Awesome)渲染的图标,本质是文本字符,但屏幕阅读器会朗读其Unicode码点(比如“uf00d”),造成完全不可理解的噪音。直接删掉字体标签也不行——它可能承担关键交互功能。
标准解法是两步走:屏蔽字体字符本身,再用真实文本传达意图:
<button> <span aria-hidden="true"></span> <span class="sr-only">关闭弹窗</span> </button>
-
aria-hidden="true"让辅助技术彻底忽略该,防止误读乱码 -
sr-only类需用CSS实现视觉隐藏但保留屏幕阅读器可读(position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;) - 禁用
aria-label直接写在<button></button>上——它会覆盖内部文本,导致表单验证丢失关联
图片图标(<img>)的alt不能省略也不能套模板
哪怕只是个16×16像素的放大镜PNG,只要它出现在交互区域(比如搜索框右侧),就必须有准确alt。空alt=""只适用于纯装饰、无功能的分隔线或背景纹理图。
- 功能型图标
alt必须匹配操作目的:搜索框旁的放大镜,alt="搜索";下载按钮旁的向下箭头,alt="下载当前文件" - 禁止写
alt="icon-search"或alt="放大镜图片"——前者暴露实现细节,后者没传递行为意图 - 如果同一图标在不同上下文有不同作用(比如“齿轮”在设置页是“打开设置”,在用户页是“编辑资料”),
alt必须动态更新,不能复用静态值
避免用<div>模拟图标+JS劫持交互
<p>最危险的写法是:<code><div class="icon-close"></div> + onclick绑定关闭逻辑。这种结构对键盘用户完全不可达:Tab键无法聚焦,Enter/Space键无法触发,屏幕阅读器读作“division”,没有任何上下文。
- 必须用语义化容器承载:按钮就用
<button></button>,链接就用<a></a>,再把图标嵌入其中
- 若因样式限制无法用
<button></button>,至少补全role="button" + tabindex="0" + aria-label,并监听keydown事件响应Enter/Space
- 所有图标交互必须支持键盘焦点、键盘触发、焦点状态视觉反馈(
:focus-visible),三者缺一不可
真正难的不是加几个属性,而是每次放图标前问自己一句:如果这个像素块消失了,用户还能知道接下来该做什么吗?答案决定你该用aria-label、alt,还是直接换回带文字的按钮。
<button></button>,链接就用<a></a>,再把图标嵌入其中<button></button>,至少补全role="button" + tabindex="0" + aria-label,并监听keydown事件响应Enter/Space:focus-visible),三者缺一不可











