Mermaid.js Accessibility Guide: Making Diagrams Screen-Reader Friendly
Learn how to add ARIA labels, alt text, and accessible descriptions to Mermaid.js diagrams so they work with screen readers and meet WCAG standards.
# Mermaid.js Accessibility Guide: Making Diagrams Screen-Reader Friendly
Mermaid.js is the de facto standard for text-to-diagram rendering in developer docs. But out of the box, rendered SVG diagrams are invisible to screen readers. Every , , and element sits in the DOM without any semantic meaning.
If your docs live on a public site, an internal wiki, or a product help center, inaccessible diagrams mean you are shutting out users who rely on assistive technology — and potentially violating WCAG 2.1 requirements.
This guide covers every technique available in Mermaid 10+ to make diagrams accessible: ARIA attributes, descriptive text, accessible color palettes, and integration patterns for common platforms.
The Problem: Mermaid SVG Is Not Accessible by Default
A Mermaid flowchart rendered from this source:
graph TD
A[Login] --> B{Dashboard}
B -->|Admin| C[Admin Panel]
B -->|User| D[User Profile]Try in Editor →Produces SVG output that a screen reader encounters as an opaque blob of vector paths. There are no landmark roles, no heading structure, no text alternatives. The user hears nothing useful.
Solution 1: The `accessibility` Config (Mermaid 10.3+)
Mermaid 10.3 introduced a dedicated accessibility configuration object. This is the most important feature for diagram accessibility:
mermaid.initialize({
accessibility: {
title: "User Authentication Flow",
description: "Flowchart showing login redirecting to Admin Panel or User Profile based on role",
svgRole: "img"
}
});What Each Setting Does
| Option | Values | Effect |
|---|---|---|
| `title` | string | Sets the ` |
| `description` | string | Sets the ` |
| `svgRole` | `"img"` or `"graphics-document"` | `"img"` treats the diagram as a single image (default); `"graphics-document"` exposes individual nodes |
svgRole: "img" is the recommended default. It tells the screen reader to announce the title and description and treat the entire SVG as one element. Users can skip past it or drill in.
svgRole: "graphics-document" makes each node individually navigable — useful for large architectural diagrams where exploring node-by-node is the goal.
Complete Example: Accessible Flowchart
<pre class="mermaid">
graph TD
A[Start] --> B{Is User Logged In?}
B -->|Yes| C[Load Dashboard]
B -->|No| D[Redirect to Login]
</pre>
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>
mermaid.initialize({
startOnLoad: true,
accessibility: {
title: "Login Decision Flow",
description: "Decision tree: if user is logged in, load dashboard; otherwise redirect to login page",
svgRole: "img"
}
});
</script>Screen reader output: *"Login Decision Flow — image. Decision tree: if user is logged in, load dashboard; otherwise redirect to login page."*
Solution 2: Per-Diagram ARIA with `%%{init}``
When you have multiple diagrams on one page, set accessibility metadata per-diagram using the %%{init}` directive:
%%{init: { "accessibility": { "title": "Microservices Data Flow", "description": "Data moving from API Gateway through Auth Service to Database", "svgRole": "img" } } }%%
graph LR
Client --> Gateway
Gateway --> Auth
Auth --> DBTry in Editor →This overrides the global accessibility config for that specific diagram only.
Solution 3: Node-Level Descriptions with `accDescr`
Mermaid 10.4+ supports per-node accessible descriptions using a special syntax:
graph TD
A["Login Page<br/>accDescr: Username and password form with submit button"]
B["Dashboard<br/>accDescr: Main overview showing charts, recent activity, and quick actions"]Try in Editor →When svgRole is set to "graphics-document", each node's accDescr is exposed as the accessible description for that individual SVG group element.
Note: accDescr is still experimental in Mermaid 10.x. Test with your target screen reader (NVDA, JAWS, VoiceOver) before relying on it in production.
Solution 4: Wrapping Diagrams in Semantic HTML
The simplest and most reliable approach for any Mermaid version — wrap the diagram in a with explicit aria- attributes:
<figure role="img" aria-labelledby="diagram-caption" aria-describedby="diagram-desc">
<figcaption id="diagram-caption">User Authentication Flow</figcaption>
<p id="diagram-desc" class="sr-only">
Flowchart showing login page redirecting authenticated users to the dashboard
and unauthenticated users back to the login page with an error message.
</p>
<pre class="mermaid">
graph TD
A[Login] --> B{Valid?}
B -->|Yes| C[Dashboard]
B -->|No| D[Error]
</pre>
</figure>The .sr-only class (screen-reader-only) hides the description visually while keeping it in the accessibility tree:
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}Accessible Color Palettes
Color-blind users (roughly 8% of males) may not distinguish red/green node colors. Use Mermaid themes or custom themeVariables with accessible palettes:
mermaid.initialize({
theme: 'base',
themeVariables: {
// Accessible palette: high contrast, colorblind-safe
primaryColor: '#4A90D9', // Blue instead of red
primaryTextColor: '#FFFFFF',
secondaryColor: '#F5A623', // Orange instead of green
tertiaryColor: '#7B68EE', // Medium slate blue
lineColor: '#333333',
textColor: '#1A1A1A'
}
});Tools to validate your palette:
- WebAIM Contrast Checker — ensure 4.5:1 ratio for normal text
- Coblis Color Blindness Simulator — preview how your diagram looks with different types of color blindness
- Mermaid's built-in neutral and forest themes already use high-contrast accessible defaults
Platform-Specific Tips
GitHub Markdown
GitHub's Mermaid renderer automatically applies svgRole: "img" with the diagram code as the accessible name. You cannot customize title/description in GitHub markdown — wrap your code block in an HTML with aria- attributes instead.
Docusaurus
// docusaurus.config.js
themeConfig: {
mermaid: {
options: {
accessibility: {
title: "", // set per-diagram via %%{init}
description: "",
svgRole: "img"
}
}
}
}MermaidEditor.lol
MermaidEditor renders diagrams client-side. Copy the SVG output and add and elements manually before embedding in your page — or use the PNG export and add alt text on the tag.
Notion / Confluence / Obsidian
These platforms embed Mermaid as static images. The only accessible path is to add a caption or alt text in the platform's own image block settings.
Testing Your Diagrams for Accessibility
- axe DevTools (browser extension): Run an automated audit. It flags SVGs missing accessible names.
- Screen reader manual test: Open your page in Chrome with ChromeVox or use VoiceOver (macOS) / NVDA (Windows). Navigate to the diagram and listen.
- Lighthouse: The accessibility audit in Chrome DevTools checks for image alt text — it will flag bare SVGs without
role="img"andaria-label.
Quick Checklist
- [ ] Every diagram has a title and description set via accessibility config or %%{init}`
- [ ] svgRole is explicitly set to "img" or "graphics-document"
- [ ] Color palette passes WCAG AA contrast (4.5:1 minimum)
- [ ] Red/green are never the sole differentiators between node meanings
- [ ] Large diagrams have a text summary adjacent in the page
- [ ] Tested with at least one actual screen reader
FAQ
Does Mermaid support WCAG 2.1 AA compliance?
Mermaid itself does not guarantee compliance — it is a rendering library. But with the accessibility config, proper color choices, and semantic HTML wrappers, you can build WCAG AA-compliant pages that include Mermaid diagrams.
Can screen readers read text inside Mermaid nodes?
Only if svgRole is set to "graphics-document" AND you have added accDescr to each node (Mermaid 10.4+). For broader compatibility, use svgRole: "img" with a comprehensive title and description — this is the approach most platforms use.
What about keyboard navigation within diagrams?
Mermaid does not currently support keyboard-navigable diagrams out of the box. For interactive exploration of complex diagrams, consider exporting the SVG and adding your own tab-indexable elements, or providing a text-based table equivalent of the diagram structure.
Are Mermaid themes accessible?
The neutral and forest themes use high-contrast color pairs. The default and dark themes may fail contrast checks. Always verify with WebAIM or axe DevTools.
Is there a Mermaid plugin that handles accessibility automatically?
Not yet. The accessibility config in Mermaid 10.3+ is the official solution. Community plugins for popular SSGs (Docusaurus, MkDocs) are beginning to add auto-generated descriptions from diagram source code, but these are still experimental.