svg和字体图标无默认可访问性,必须显式添加语义:功能型svg用role="img"+或aria-label,装饰性加aria-hidden="true";字体图标须关联文本或包裹sr-only文字,禁用aria-label直接写在上。

SVG 和字体图标本身不自动具备可访问性,必须显式添加语义标记;否则屏幕阅读器会跳过、误读,甚至把图标当装饰静音处理。
SVG 图标必须配 <title></title> 或 aria-label,不能只靠 alt
<img src="icon.svg"> 可以用 alt,但内联 <svg></svg> 不支持该属性——浏览器直接忽略。不加语义,它在可访问树里就是个“透明容器”。
- 功能型 SVG(如“删除按钮”):外层加
role="img",内部加<title>删除当前项目</title>,再补aria-hidden="true"给所有<path></path>避免重复播报 - 图文共存场景(如“设置”文字旁的齿轮图标):图标用
aria-hidden="true",让屏幕阅读器只读文字,避免冗余 - 纯装饰 SVG(分割线、背景点缀):直接加
aria-hidden="true",不加<title></title>,否则会被误读为有含义内容
字体图标(<i class="fa-trash"></i>)必须包裹或关联文本语义
字体图标本质是 Unicode 字符,屏幕阅读器默认读出字形名(如“U+F1F8”),毫无意义。它自己不携带任何语义,全靠你补。
- 独立图标按钮:用
<button><i class="fa-trash"></i><span class="sr-only">删除当前行</span></button>,span.sr-only用 CSS 视觉隐藏但保留可访问性 - 图标+文字同级(如菜单项):确保文字本身已说明功能,图标仅作视觉强化,此时给
<i></i>加aria-hidden="true"即可 - 绝对避免:
aria-label直接写在<i></i>上——部分旧版 NVDA 和 JAWS 会忽略,且与父级<button></button>的名称冲突
动态图标(Vue/React 组件)要透传可访问性 props
封装 <svgicon name="search"></svgicon> 或 <vabicon name="user"></vabicon> 时,若组件内部是内联 SVG,name 本身不是可访问文本,必须允许传入 aria-label 或 title。
- 推荐接口:
<svgicon name="download" aria-label="下载报告"></svgicon>,组件内部将aria-label挂到外层<svg></svg>上,并设role="img" - 不推荐硬编码:
<svgicon name="download"></svgicon>自动塞aria-label="download"——英文词对中文用户无意义,且无法覆盖上下文差异 - SSR 场景下注意:服务端渲染时若
aria-label为空或未传,组件应 fallback 到aria-hidden="true",而非留空导致读屏报“未命名图形”
最容易被忽略的是:SVG Sprite 中的 <use href="icons.svg#home"></use> 无法在外部注入 <title></title>,因为 <title></title> 必须在原始 <symbol></symbol> 内定义——这意味着图标资产源头就要带语义,不能等用的时候再补。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











