关于 mermaid
面向 Mermaid 图表编写、生成和审查的无障碍技能,仅在项目使用 Mermaid 时适用。它关注元数据、渲染输出及发布平台,并强调复杂图表应提供可见的结构化替代内容。
主要功能
- 01编写图表标题与描述元数据
- 02检查 Mermaid 版本及渲染结果
- 03为复杂图表提供结构化替代
- 04审查 SVG 与嵌入方式
- 05检查颜色对比度与主题
- 06改善节点、关系和阅读顺序
适用场景
- 01审查 Mermaid 图表的无障碍性
- 02为流程图补充步骤或决策表
- 03验证发布平台中的图表输出
- 04检查深色主题下的对比度
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mgifford/ accessibility-skills --skill mermaid安装后在 Claude Code 中输入/mermaid确认已加载。
附带文件SYNC.md
详细介绍
Mermaid 图表无障碍技能
权威来源:
mgifford/ACCESSIBILITY.md中的examples/MERMAID_ACCESSIBILITY_BEST_PRACTICES.md此技能源自该文件。如有疑问,以示例为准。
编写、生成或审查 Mermaid 图表时,请遵循以下规则。 仅当项目使用 Mermaid 图表时,才加载此技能。
核心要求
Mermaid 内容的无障碍性取决于四个层面:(1)图表源代码及其无障碍元数据,(2)确切的 Mermaid 渲染器及配置,(3)生成的 SVG/栅格输出,以及(4)发布平台如何嵌入并呈现该输出。除非已证明渲染后的节点/关系具有实用语义,否则生成的 Mermaid 图表属于非文本内容——请测试最终发布的输出,而不只是源代码或编辑器预览。
编写图表之前,先判断是否确实需要图表——标题、简短列表、表格或几句话或许能更清楚地传达信息。当关系、顺序、分支、层级、时间安排或空间分组能实质性地提升理解时,Mermaid 才有用。
严重程度级别(本技能)
| 级别 | 含义 |
|---|---|
| 严重 | 图表传达了重要信息,但没有无障碍标题或替代文本;元数据使用了错误语法,因而被静默忽略 |
| 较严重 | 有标题,但复杂图表没有描述;对比度不合格 |
| 中等 | 复杂图表类型没有可见的结构化替代内容;命名边缺少上下文 |
| 轻微 | ID 重复;未验证渲染器版本 |
严重:使用正确的 accTitle/accDescr 语法——不要加 %% 前缀
%% 是 Mermaid 的注释前缀。 写成 %%accTitle … 或
%%accDescr … 的行是注释,会被静默忽略——因此完全不会生成无障碍元数据,尽管看起来似乎有效。
# WRONG — these are Mermaid comments and do nothing
%%accTitle This is ignored as a comment
%%accDescr This is also ignored as a comment
正确语法是直接使用 accTitle: 和 accDescr:,不加注释前缀:
flowchart TD
accTitle: Account recovery decision flow
A[Submit email address] --> B{Account found?}
B -->|Yes| C[Send recovery link]
B -->|No| D[Show recovery help]
单行描述使用冒号:
flowchart LR
accTitle: Publishing workflow
accDescr: Content moves from drafting through accessibility review to publication.
A[Draft] --> B[Accessibility review] --> C[Publish]
对于多行描述,省略 accDescr 后的冒号并使用花括号:
flowchart TD
accTitle: Account recovery decision flow
accDescr {
A user submits an email address. If an account is found, the system sends
a recovery link and confirms that it was sent. If no account is found,
the system shows recovery help and offers a support contact.
}
A[Submit email address] --> B{Account found?}
B -->|Yes| C[Send recovery link]
B -->|No| D[Show recovery help]
Mermaid 没有规定通用的 100 字符标题上限或 500 字符描述上限——请使用能在页面上区分该图表的最短标题,并确保描述足够简洁,能作为有用的图像描述(详细步骤应移至可见的结构化 HTML 中,而不是全部塞进 accDescr)。
不要杜撰指令,例如 %%a11y-node 或 %%a11y-edge——这些不是标准 Mermaid 语法;除非项目专用预处理器实现了它们,否则它们只是注释,绝不应被描述为 Mermaid 功能。
请使用项目的确切 Mermaid 版本解析并渲染源代码,以发现语法支持和图表类型方面的差异——不同版本和图表类型对 accTitle/accDescr 的支持各不相同。
编写实用的标题和描述
**标题:**指出主题,使其能与页面上的其他内容区分;仅在有帮助时注明图表类型;避免使用文件名/内部 ID/通用标签(例如“图表”)。示例:“账户恢复决策流程”、“支付服务请求顺序”、“订单状态与允许的转换”。
**描述:**说明用途、起始上下文、主要元素/参与者、关键顺序/层级/关系、重要决策/例外情况/结果,以及完整替代内容所在的位置。不要只罗列颜色和形状(“一个蓝色矩形指向一个绿色菱形”描述的是外观,而非含义),也不要把每个节点标签都压成一个长句——这会增加浏览难度并丢失结构。
还应提供可见的标题/描述——页面标题或图注能帮助所有人,而不仅仅是使用辅助技术的用户:
<figure aria-labelledby="recovery-flow-heading">
<h2 id="recovery-flow-heading">Account recovery flow</h2>
<pre class="mermaid">
flowchart TD
accTitle: Account recovery decision flow
accDescr: A recovery request either sends a link or offers additional help.
A[Submit email address] --> B{Account found?}
</pre>
<figcaption><a href="#recovery-flow-description">Read the account recovery steps</a>.</figcaption>
</figure>
(仅当 Mermaid 源代码直接嵌入 HTML 时,才需要对 > 进行转义——Markdown Mermaid 代码围栏无需转义。)
严重:为复杂图表提供可见的结构化替代内容
accDescr 会创建 SVG 描述,而不是可导航的文档结构。
复杂图表需要包含标题、列表、表格和链接的可见 HTML。
| Mermaid 图表类型 | 有用的结构化替代内容 |
|---|---|
| 流程图/决策树 | 有序步骤 + 嵌套列表或决策表(条件 → 结果) |
| 时序图 | 参与者列表 + 按时间顺序排列的消息表 |
| 状态图 | 状态定义 + 转换表(触发条件、源状态、目标状态、结果) |
| 类图 | 类定义、属性、方法、继承关系、关系表 |
| 实体关系图 | 实体定义、键、属性、基数、关系表 |
| 甘特图/时间线 | 任务/事件表,包含日期、时长、负责人、状态、依赖项 |
| 饼图/XY 图/象限图/雷达图/桑基图 | 发现结果摘要 + 包含单位的底层数据表 |
| 思维导图/树形图 | 适当嵌套的标题或列表层级 |
| 架构图/C4 图/块图 | 组件清单、职责、边界、关系表 |
| Git 图 | 按时间顺序排列的分支/合并/发布历史 |
| 用户旅程图 | 按顺序排列的阶段、目标、操作、情绪、障碍、机会 |
<section id="recovery-flow-description" aria-labelledby="recovery-flow-description-heading">
<h3 id="recovery-flow-description-heading">Account recovery steps</h3>
<ol>
<li>The user submits an email address.</li>
<li>The system checks for an account:
<ul>
<li>If found, send a recovery link and confirm it was sent.</li>
<li>If not found, show recovery help and offer support.</li>
</ul>
</li>
</ol>
</section>
保持替代内容同步——尽可能根据同一份经过审核的数据模型生成图表及其替代内容;如果分别维护,则要求在同一项更改中同时更新两者、比较节点/值/边,并指定内容审核负责人。不要只提供原始 Mermaid 源码作为替代内容——它或许对开发者有帮助,但并不能为所有用户提供等效的说明。
严重:了解 Mermaid 生成的 SVG(不要手动编写不同模式)
当前 Mermaid 文档指出,渲染器会根据图表类型自动添加
aria-roledescription;如果提供了 accTitle/accDescr,则会生成 <title>/<desc> 元素,其中 aria-labelledby
引用标题,aria-describedby 引用描述
——两者分别引用,不会合并为一个 aria-labelledby:
<svg aria-labelledby="generated-title-id"
aria-describedby="generated-description-id"
aria-roledescription="flowchart-v2"
id="generated-diagram-id">
<title id="generated-title-id">Account recovery decision flow</title>
<desc id="generated-description-id">A recovery request either sends a link or offers additional help.</desc>
</svg>
除非有经过测试的理由,否则不要将两者改写为同一个 aria-labelledby 值——标签用于标识图像;描述用于提供附加信息;它们是不同的关联关系。具体的 ID/类/属性可能会随 Mermaid 版本变化——不要将生成的 ID 复制到源码中,也不要依赖未记录的内部类名。
节点级语义并非自动提供。 accTitle/accDescr 描述的是整个图表——它们不会让每个节点/边/箭头都成为有用的无障碍对象。不要自动为生成的 SVG 组添加 role="list"/role="listitem"——视觉布局不一定是列表,DOM 顺序可能与阅读顺序不一致,而且列表语义无法表达分支、基数或图关系。如果用户需要检查单个项目,请构建并测试专用的交互组件——生成的 SVG 内部结构是复杂小组件脆弱的基础。
ID 在最终 HTML 文档中必须唯一(不要求在彼此无关的页面之间唯一)。让 Mermaid 管理其生成的 ID;当一个页面包含多个内嵌图表时,检查是否存在重复项;使用 deterministicIds 配置进行稳定的快照测试;在清理/导出过程中保留每个被引用的 ID。
重要:嵌入和导出模式会改变规则
| 模式 | 责任 |
|---|---|
| 在页面中生成的内联 SVG | 保留生成的标题/描述/ARIA 引用、语言、样式和唯一 ID |
通过 <img> 引用的外部 SVG | 为 HTML 提供 alt——不要假定 SVG 内部的标题/描述会被呈现 |
| 光栅 PNG/JPEG | HTML alt + HTML 中的长篇结构化替代文本 |
<object>/iframe | 为嵌入元素提供有意义的可访问名称;测试进入/退出;提供外部 HTML 替代文本 |
| CSS 背景图片 | 仅用于装饰,或在普通 HTML 中提供相关信息 |
| PDF/办公文档导出 | 文档标签、替代文本、阅读顺序——SVG 元数据不能替代这些内容 |
| Markdown 平台渲染器 | 测试平台使用的确切 Mermaid 版本、净化器、主题和输出 |
<figure>
<img src="account-recovery-flow.svg"
alt="Account recovery either sends a reset link or provides additional support."
width="960" height="540">
<figcaption><a href="#recovery-flow-description">Read the complete account recovery steps</a>.</figcaption>
</figure>
不要仅仅因为源 SVG 包含 <title>/<desc>,就将 HTML alt 留空。
选择清晰的图表内容
节点/参与者: 使用易懂的标签,而非内部 ID;展开不常见的缩写;保持标签简洁但有意义;为视觉上相似的节点使用不同的文本标签;不要仅靠形状区分决策/流程/数据库/外部系统。
边/关系: 如果结果本身不够明确,就为分支添加标签——用“已批准”/“需要修改”代替笼统的“是”/“否”;在替代文本中保留方向和源→目标含义;解释依赖线条样式或位置但未标注的关系;不要仅用连接线颜色编码状态或关系类型。
阅读顺序/布局: 选择与内容和文档语言相匹配的方向;减少线条交叉;避免让布局仅凭位置接近就暗示关系。视觉位置不等于程序化阅读顺序——请在描述和结构化替代文本中说明预期的顺序/层级。
中等:颜色和对比度
应用 WCAG 2.2 对比度比率:普通文本 ≥4.5:1;大号文本 ≥3:1(不要仅凭 18 CSS 像素就将文本视为大号文本——请查看 WCAG 的实际定义);理解有意义的节点/边界/连接线/状态所必需的视觉信息 ≥3:1(WCAG 1.4.11)。如果标签/轮廓能保留信息,并非每种装饰性填充色都需要与每个相邻填充色达到 3:1。要符合 WCAG 2.2,使用 WCAG 2.x 对比度标准——APCA/WCAG 3 的工作仍处于研究阶段,应持续关注,但不能替代测试。
将颜色与以下方式结合使用:直接标签、线条样式、图案、带有文本替代的图标、边框样式,或结构化替代文本中的值——用于表示状态、所有权、参与者组、关键路径和选中状态。
测试实际主题——集中管理主题配置,而不是通过不稳定的内部选择器设置单个元素的样式;在每种受支持的浅色和深色显示方式中,以及实际背景/容器颜色中,测试文本/填充/边框/连接线/箭头/标签/焦点/数据标记;测试强制颜色模式,并确保 SVG 样式丢失时结构化替代文本仍可用。不要假定选择 Mermaid 的 dark 主题或添加 prefers-color-scheme 规则就会自动生成可访问的深色模式——Mermaid 更新后要重新检查主题。
响应式布局、缩放和重排
在导出的 SVG 中加入有用的 viewBox;确保图表在 200%/400% 缩放时不会被裁切;在有帮助时允许用户打开更大的视图或下载 SVG;确保可见标题/摘要/替代文本/控件可以重排;测试较长的标签和翻译;绝不要禁用浏览器缩放。WCAG 1.4.10 中针对二维布局的例外可能适用于复杂图表本身,但周围的标题、描述、控件和结构化替代文本仍需重排。
严重:键盘与交互式图表
静态图表不需要 tabindex="0"——键盘焦点应移至链接、按钮和控件,而不是每个装饰性 SVG 组。如果图表在视觉上可滚动,请确保键盘用户能够访问并滚动其容器,且不会陷入其中;同时提供不依赖二维滚动的结构化替代内容。
避免将图表设为访问重要链接或操作的唯一途径——在附近提供可见的 HTML 链接或控件。如果启用了 Mermaid 链接或点击操作:每个链接都可通过键盘访问;其用途可从无障碍名称中理解;焦点清晰可见且不被遮挡;指针和键盘操作产生相同结果;无障碍名称包含可见标签;目标尺寸以及悬停或焦点内容符合适用标准;每项操作都有等效的 HTML 途径。不要使用不可聚焦的生成式 SVG 组来模拟按钮。
对于交互式探索(选择节点、展开分支、筛选、查看详情),应在生成的静态 SVG 之外构建无障碍交互模型,或使用经过测试的组件——仅靠 Mermaid 源码加上 ARIA 属性,并不能定义无障碍的图表导航控件。
动效与动画
避免装饰性动画。如果宿主或插件添加了动画、自动更新或移动路径:在 WCAG 2.2.2 适用的情况下,提供暂停、停止或隐藏控件;遵循 prefers-reduced-motion;避免闪烁超过 WCAG 阈值;不要仅用动效作为状态变化指示;以文本形式保留最终状态。未经对确切版本和集成方式进行测试,不要声称 Mermaid 动画具有无障碍性。
关键:安全、稳定的渲染
当不可信的图表源代码能够注入标记时,可访问性和安全性可能同时受损。除非经过审核的用例要求使用其他模式,否则请保留 Mermaid 的默认设置 securityLevel: 'strict';不要仅为添加必要链接而降低安全级别(请改用 HTML 添加链接)。将用户提供的 Mermaid 源代码视为不可信输入;使用受支持的净化方式和严格的 CSP;自行管理时,通过项目的锁文件固定 Mermaid/渲染器依赖项;由平台管理渲染时,记录观察到的版本、日期、发现方法和已测试的功能。不要从未固定版本的 @latest URL 加载生产依赖项。限制源代码的大小和复杂度,避免渲染失败;发生渲染错误时,以可访问文本呈现,且不要泄露敏感细节。
自主管理与平台管理的渲染器:
| 模式 | 版本依据 | 责任 |
|---|---|---|
| 自主管理 | 包清单、锁文件、容器摘要 | 固定版本、审核更新、测试输出、保留回滚途径 |
| 平台管理(GitHub.com、Pages、Enterprise) | 版本探测、注明日期的观察记录 | 记录观察结果、测试所需功能、维护替代方案,并在平台变更后重新检查 |
| 预渲染静态导出 | 导出作业记录的版本 | 将导出文件与源代码及替代内容一并保存;测试最终嵌入环境 |
GitHub.com Markdown、GitHub Enterprise Server、GitHub Pages、本地预览和导出文件是彼此独立的渲染环境——不要根据某个环境渲染成功,就推断另一个环境也支持。GitHub Pages 不会自动继承 GitHub.com 的 Mermaid 渲染器;Jekyll 主题、插件和构建流程决定了 Mermaid 是否会在此渲染,以及如何渲染。
使用 info 图表探测托管版本:
info
这是一项实时诊断,而非固定版本的依赖项——它可能在没有提交记录的情况下发生变化,且只会报告其所显示环境中的渲染器。请将其记录为注明日期的纯文本观察结果,而不要将其作为唯一的无障碍记录:Last manually observed on GitHub.com: Mermaid x.y.z on YYYY-MM-DD.
应针对每个环境验证功能,而不只是检查版本号:所需的图表类型能够解析和渲染;accTitle/accDescr 能生成预期的标题、描述和 ARIA 关系;宿主的净化器会保留必要语义;浅色、深色和强制颜色模式下的内容仍清晰易懂;同一页面上的多个图表不会产生冲突的 ID;渲染失败时仍可使用结构化替代内容。
编写与审核工作流
**编写前:**判断图表是否能实质性地提升理解;明确用途、受众、关键关系和替代格式;确认目标渲染器支持该图表类型和无障碍语法。
**编写时:**添加有效的 accTitle:/accDescr: 行(不要添加 %% 前缀);使用清晰的标签;确保视觉复杂度适当;避免仅依靠颜色或形状表达含义;在编写源代码的同时撰写结构化替代内容;将必要的链接和控件保留在 HTML 中。
**发布前:**使用固定的生产版本进行渲染(或记录平台管理的版本并验证功能);检查生成的 SVG 和最终的无障碍树;根据图表验证结构化替代内容;测试所有支持的主题、缩放级别、视口和导出格式;在实际宿主中测试(不要只看编辑器预览);记录审核者、版本、日期和限制。
**AI 生成的图表:**将其视为草稿——根据源材料核实每个节点、边、值和关系;重写通用的无障碍描述;检查结构化替代内容是否与最终图表一致;拒绝虚构的 Mermaid 指令;不要仅凭视觉渲染成功就推断其具备无障碍性、安全性或符合规范。
语法检查与自动化验证
源代码检查: 确认源代码能被目标渲染器准确解析;
存在 accTitle:,且未被注释(即未以 %% 开头);
存在 accDescr: 或 accDescr { ... },且未被注释;值非空;
不会将禁止使用的自定义指令误认为真实语法;
复杂图表引用了可见的结构化替代内容。不要强制采用任意的通用字符数限制。
渲染输出检查: 生成的 <title>/<desc> 存在;aria-labelledby
能解析到标题;aria-describedby 能解析到描述;最终页面中的 ID
唯一;清理/优化未移除被引用的元素;不存在意外的可聚焦后代元素;交互元素具有
名称/角色/状态/键盘行为/可见焦点;渲染错误以文本形式显示。
对比度检查需要检查每种受支持主题下实际渲染的元素组合(文本与有效 背景、边界、连接线、焦点状态)——“单色”并非跳过对比度测试的理由。
自动化无法判断描述是否等效、阅读顺序是否合理,或图表是否易于理解——必须进行人工审核和用户评审。
测试
- **内容/等效用途:**明确图表应回答的问题;识别每个重要关系/分支/数值;先依据可视化图表作答,再仅依据标题/描述/结构化 替代内容作答;比较可用信息和结论;同时修正两种呈现方式
- **键盘:**确认静态 SVG 不会成为不必要的 Tab 停靠点;操作每个图表链接/控件/弹出窗口;检查可见焦点和逻辑顺序; 进入和离开可滚动图表时不会被困住;确认每项操作都有等效的 HTML 操作路径
- **屏幕阅读器:**确认计算得出的无障碍名称/描述;检查最终 宿主将图表呈现为图像/图形/文档中的哪一种;按标题/列表/表格阅读结构化替代内容;确认没有 重复/过多的播报
- **视觉/低视力:**常规和大号文本;200%/400% 缩放;窄视口/不同方向; 每种浅色/深色呈现方式;强制颜色模式; 确认标签/节点/线条/箭头/图例始终可见;较长的译文不会相互重叠
- **导出/平台:**测试原始 Markdown/源代码预览,以及经过清理/优化后的 生产页面;记录每个经过测试的渲染器是固定版本还是由平台管理;测试内联 SVG、外部 SVG 和栅格图变体;测试打印/PDF;测试 JavaScript 不可用或渲染失败时的表现; 测试同一页面上的多个图表是否存在重复 ID;Mermaid/插件/主题/宿主更新后重新测试
常见问题
| 问题 | 修正方法 |
|---|---|
编写 %%accTitle 或 %%accDescr | 使用 accTitle: 和 accDescr:,不要添加 %% 注释前缀 |
| 强制要求任意的 100 字符/500 字符限制 | 编写简洁实用的元数据;通过可见结构呈现详细信息 |
| 将渲染成功视为无障碍性达标的证明 | 检查最终 SVG、无障碍树、宿主环境和替代内容 |
复杂图表仅依赖 <desc> | 提供可见的标题、列表、表格或正文 |
| 仅将原始 Mermaid 源码作为替代内容 | 提供适合任务的通俗易懂的表示形式 |
| 为每个生成的 SVG 组添加列表语义 | 将图表作为整体处理,或构建经过测试的专用界面 |
用 aria-labelledby 替换描述所用的 aria-describedby | 保持标签和描述的关联关系彼此独立 |
| 使用时间戳/随机字符串生成标题 ID | 让 Mermaid 管理 ID;需要稳定性时使用 deterministicIds |
将 xmlns 视为通用无障碍属性 | 它是独立序列化 SVG 的必需属性,并非通用的内联 SVG 元数据 |
臆造 %%a11y-node/%%a11y-edge 语法 | 使用受支持的 Mermaid 语法或有文档说明的真实预处理扩展 |
| 将 18 CSS 像素视为大号文本的判定阈值 | 应采用 WCAG 对大尺寸文本的实际定义 |
| 认为深色 Mermaid 主题符合深色模式要求 | 在每种受支持的呈现方式下测试实际颜色 |
| 让静态图表可通过键盘聚焦 | 不要将静态图形放入 Tab 键顺序 |
从未固定版本的 @latest 依赖加载 Mermaid | 固定并审查生产环境中的渲染器版本 |
| 将平台管理的渲染器描述为已固定版本 | 记录观察到的版本、日期、发现方式和已测试的功能 |
| 假设 GitHub Pages 使用 GitHub.com 的 Mermaid 版本 | 确认 Pages 主题/插件/构建流水线提供的渲染器 |
无必要地使用 securityLevel: 'loose' | 保持严格的安全默认设置;将必要的交互放在 HTML 中 |
完成标准检查清单
- 已使用正确语法添加
accTitle:(无%%前缀),且内容简洁、唯一 - 已添加
accDescr:或accDescr { ... },说明用途和关键关系 - 已确认/记录实际发布环境中使用的 Mermaid 版本
- 已验证生成的 SVG:
<title>、<desc>、aria-labelledby(标题)和aria-describedby(描述)保持为彼此独立的关联关系 - 复杂图表有与图表类型相匹配的可见结构化替代内容
- 图表和替代内容由相同数据/变更同步生成
- 最终页面中的所有 ID 均唯一
- 装饰元素已从无障碍树中排除;未在生成的组上臆造
role="list" - 命名边包含上下文标签(如“是,继续前往 X”,而非“是”)
- 已在浅色、深色和强制颜色模式下验证对比度
- 静态图表不会造成不必要的 Tab 停靠点;必要的链接也以真实 HTML 链接形式提供
- 已分别测试每种发布环境(GitHub.com、GitHub Pages、本地预览、导出)
- 除非记录并审查了例外情况,否则保留
securityLevel: 'strict' - 已使用屏幕阅读器测试
关键 WCAG 标准
- 1.1.1 非文本内容(A)——若缺少标题/替代内容则至关重要
- 1.3.1 信息和关系(A)
- 1.4.1 使用颜色(A)
- 1.4.3 对比度(最低)(AA)
- 1.4.10 重排(AA)
- 1.4.11 非文本对比度(AA)
- 2.1.1 键盘(A)
- 2.4.7 焦点可见(AA)
- 4.1.2 名称、角色、值(A)
- 4.1.3 状态消息(AA)
参考资料
- 完整的最佳实践指南
- Mermaid 图表类型参考
- Mermaid 转换最佳实践
- Mermaid:无障碍选项
- Mermaid:安全性
- GitHub:检查 Mermaid 版本
- WAI-ARIA 1.2:
aria-roledescription
**标准展望:**这些规则以 WCAG 2.2 AA 为目标。 请关注:https://www.w3.org/TR/wcag-3.0/