How `aria-labelledby` and `prefers-reduced-motion` Work in Diagram-Design
The diagram-design repository uses aria-labelledby to wire SVG diagrams to semantic <title> and <desc> elements for screen reader announcements, while employing prefers-reduced-motion CSS media queries and JavaScript detection to serve static frames to users with vestibular sensitivities.
Diagram-design is an open-source SVG diagramming framework that embeds accessibility directly into its markup templates and validation pipelines. The repository enforces WCAG-compliant patterns through automated checks in cathrynlavery/diagram-design, ensuring that every diagram remains perceivable to assistive technology users and comfortable for those who require reduced motion. This article examines the specific implementations of aria-labelledby and prefers-reduced-motion based on the actual source code.
Semantic SVG Accessibility with aria-labelledby
Wiring Diagrams to Title and Description Elements
Every SVG diagram in the repository carries role="img" and references two descriptive elements via the aria-labelledby attribute. According to the validation logic in skills/diagram-design/scripts/self_check.py, the attribute must list the <title> element ID first, followed by the <desc> element ID. This ordering ensures screen readers announce a concise label before the longer explanation, providing hierarchical context for complex diagrams.
The validation script programmatically inspects each SVG to confirm that:
- The first ID in
aria-labelledbypoints to a<title>element containing the diagram's name - The second ID points to a
<desc>element providing detailed description
Automated Validation Pipeline
The repository's quality assurance relies on skills/diagram-design/scripts/self_check.py to enforce semantic correctness. This script parses the aria-labelledby attribute value and verifies that the referenced elements exist and appear in the correct sequence, preventing accessibility regressions before diagrams reach production.
<svg viewBox="0 0 1000 600"
xmlns="http://www.w3.org/2000/svg"
role="img"
aria-labelledby="my-diagram-title my-diagram-desc">
<title id="my-diagram-title">Order fulfillment process</title>
<desc id="my-diagram-desc">
Shows the flow from a customer order through support closure.
</desc>
<!-- diagram content … -->
</svg>
Motion Sensitivity Support with prefers-reduced-motion
CSS Media Query Fallbacks
For users with vestibular disorders or motion sensitivity, diagram-design implements a robust fallback strategy using the prefers-reduced-motion media query. As documented in skills/diagram-design/references/animation.md, the CSS immediately displays the static final frame of any animation and suppresses playback controls when the user's system preferences indicate reduced motion.
The @media (prefers-reduced-motion: reduce) block targets the data-motion-state="reduced" attribute, ensuring that animated layers render at full opacity without transitions while hiding interactive controls that might trigger unwanted movement.
@media (prefers-reduced-motion: reduce) {
/* Show the final static frame and hide playback UI */
.diagram[data-motion-state="reduced"] .playback-controls {
display: none;
}
.diagram[data-motion-state="reduced"] .animated-layer {
animation: none;
opacity: 1; /* show the completed frame */
}
}
JavaScript Detection in template-motion.html
The motion-enabled template at skills/diagram-design/assets/template-motion.html contains detection logic that runs before rendering. The script uses window.matchMedia('(prefers-reduced-motion: reduce)') to check system settings and applies data-motion-state="reduced" to the document root when necessary, immediately triggering the CSS fallbacks without requiring page reloads.
const reduce = matchMedia('(prefers-reduced-motion: reduce)');
if (reduce.matches) {
document.documentElement.dataset.motionState = 'reduced';
}
Verification Scripts for Compliance
Two dedicated verification scripts ensure motion accessibility standards:
- verify-motion.py: Confirms that animated diagrams include the
prefers-reduced-motionCSS fallback - verify-semantic-motion.py: Validates that semantic motion alternatives exist for complex animations
These automated checks parse the diagram source files to ensure compliance before content reaches the main branch.
Summary
- Semantic SVG markup: Every diagram uses
role="img"andaria-labelledbyto explicitly link to<title>and<desc>elements, ensuring screen readers announce diagram purpose and context in the correct order. - Automated accessibility validation: The
self_check.pyscript enforces correctaria-labelledbyordering, whileverify-motion.pyandverify-semantic-motion.pyensure motion fallbacks exist and function correctly. - Reduced motion compliance: CSS media queries detect
prefers-reduced-motion: reduceto display static frames, supported by JavaScript detection intemplate-motion.htmlthat setsdata-motion-state="reduced"on the root element. - Template-driven implementation: Base templates in
assets/template.htmlandassets/template-motion.htmlprovide the foundational markup patterns that propagate accessibility features across all generated diagrams.
Frequently Asked Questions
How does diagram-design ensure screen readers announce diagram content correctly?
The repository enforces a strict markup pattern where every SVG carries role="img" and uses aria-labelledby to reference a <title> element (for the concise name) and a <desc> element (for the detailed description). The skills/diagram-design/scripts/self_check.py validation script automatically checks that these IDs exist and appear in the correct order, preventing silent failures where screen readers might skip content or read descriptions out of context.
What happens when a user enables prefers-reduced-motion in their browser?
When the system reports prefers-reduced-motion: reduce, the JavaScript in assets/template-motion.html immediately sets data-motion-state="reduced" on the root HTML element. This triggers CSS rules that display the static final frame of any animation at full opacity while hiding playback controls via display: none, effectively eliminating vestibular triggers while preserving all semantic information.
Which files contain the accessibility validation logic?
The primary validation occurs in skills/diagram-design/scripts/self_check.py for semantic SVG markup, scripts/verify-motion.py for motion fallback detection, and scripts/verify-semantic-motion.py for semantic motion alternatives. These scripts parse the diagram source files to ensure compliance before content reaches production, catching missing aria-labelledby attributes or absent reduced-motion fallbacks during the CI pipeline.
Can animated diagrams still convey information when motion is disabled?
Yes. The prefers-reduced-motion implementation in diagram-design always renders the static final frame of any animation sequence when motion is reduced. This guarantees that temporal information remains accessible as a complete visual state, ensuring no semantic content is lost for users who require reduced motion, while verify-motion.py confirms this fallback exists for every animated diagram.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →