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

SVG 和字体图标本身不自动具备可访问性,必须显式添加语义标记;否则屏幕阅读器会跳过、误读,甚至把图标当装饰静音处理。
SVG 图标必须配 <title> 或 aria-label,不能只靠 alt
<img src="icon.svg"> 可以用 alt,但内联 <svg> 不支持该属性——浏览器直接忽略。不加语义,它在可访问树里就是个“透明容器”。
- 功能型 SVG(如“删除按钮”):外层加
role="img",内部加<title>删除当前项目</title>,再补aria-hidden="true"给所有<path>避免重复播报 - 图文共存场景(如“设置”文字旁的齿轮图标):图标用
aria-hidden="true",让屏幕阅读器只读文字,避免冗余 - 纯装饰 SVG(分割线、背景点缀):直接加
aria-hidden="true",不加<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>加aria-hidden="true"即可 - 绝对避免:
aria-label直接写在<i>上——部分旧版 NVDA 和 JAWS 会忽略,且与父级<button>的名称冲突
动态图标(Vue/React 组件)要透传可访问性 props
封装 <SvgIcon name="search" /> 或 <VabIcon name="user" /> 时,若组件内部是内联 SVG,name 本身不是可访问文本,必须允许传入 aria-label 或 title。
立即学习“前端免费学习笔记(深入)”;
- 推荐接口:
<SvgIcon name="download" aria-label="下载报告" />,组件内部将aria-label挂到外层<svg>上,并设role="img" - 不推荐硬编码:
<SvgIcon name="download" />自动塞aria-label="download"——英文词对中文用户无意义,且无法覆盖上下文差异 - SSR 场景下注意:服务端渲染时若
aria-label为空或未传,组件应 fallback 到aria-hidden="true",而非留空导致读屏报“未命名图形”
最容易被忽略的是:SVG Sprite 中的 <use href="icons.svg#home"> 无法在外部注入 <title>,因为 <title> 必须在原始 <symbol> 内定义——这意味着图标资产源头就要带语义,不能等用的时候再补。



















