内联SVG必须用<title>和<desc>而非alt,且二者须为SVG前两个子元素;<title>等价于alt需简明,<desc>补充上下文;纯装饰SVG仍需空<title>并设aria-hidden="true";role="img"和aria-label冗余有害;viewBox必须合法;动态生成SVG须手动注入<title>和<desc>。

内联 SVG 必须加 <title> 和 <desc>,否则屏幕阅读器基本读不出内容,搜索引擎也难索引。
为什么 <title> 不能只靠 CSS 隐藏?
很多开发者用 display: none 或 visibility: hidden 隐藏 <title>,以为“视觉上不显示=不影响设计”,但这样会直接让辅助技术跳过该元素。SVG 的 <title> 不是装饰性标签,它是可访问性入口点。
- 必须保留在 DOM 中,且不能被
aria-hidden="true"或隐藏样式屏蔽 - 推荐用
position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;实现“视觉隐藏但语义保留” - 如果 SVG 是纯装饰(比如背景分隔线),才可用
aria-hidden="true"+focusable="false"显式排除
<desc> 和 alt 属性到底谁管用?
内联 SVG 没有 alt 属性——那是 <img> 标签的。唯一合法、被广泛支持的描述方式是 <desc> 元素,且必须和 <title> 同级、同父容器(即都在根 <svg> 内)。
-
<title>是简短名称(类似按钮文字),<desc>是补充说明(类似 tooltip 或长描述) - 两者都应使用中文,避免机器翻译腔;避免重复,比如
<title>搜索图标</title><desc>点击打开搜索框</desc> - 若 SVG 用于链接或按钮,还需在外层加
role="img"并绑定aria-labelledby,例如:<a href="#" role="img" aria-labelledby="svg-title-1"><svg><title id="svg-title-1">首页</title><desc>返回网站主页面</desc><path d="..." /></svg></a>
嵌套 <g> 和多图标的 SVG 怎么打标?
一个 <svg> 里有多个功能区域(比如带图标的菜单项、状态指示组合图),不能只靠顶层 <title> 覆盖全部。需要按逻辑分组,给每个 <g> 加独立语义。
立即学习“前端免费学习笔记(深入)”;
- 每个有意义的
<g>应包含自己的<title>(可选<desc>),并设role="group"或role="img" - 避免在
<path>或<circle>上直接加aria-label—— 大部分屏幕阅读器不识别这些元素上的 ARIA - 如需动态更新描述(比如加载中图标变“处理中”),直接操作
document.getElementById("my-desc").textContent = "处理中...";即可,无需重绘 SVG
最常被忽略的一点:内联 SVG 的 <title> 和 <desc> 必须在首次渲染时就存在。用 JS 动态插入它们,或者等 React/Vue 组件挂载后再 append,都会导致初始无障碍树缺失,部分读屏器不会补读。



















