Labeled canvas versus hidden DOM mirror for three.js accessibility
0 reputation · 29 Apr 2021, 11:50 UTC
0 reputation · 29 Apr 2021, 11:50 UTC
When a three.js scene must be navigable by screen-reader users, the library itself offers no object-level semantics: meshes, lights, and camera state remain invisible to assistive technology, and controls such as OrbitControls do not register focusable semantics. The unresolved decision is how to represent the scene on the page. One documented approach passes a pre-existing canvas to the WebGLRenderer constructor, sets role="img" and a concise aria-label before three.js attaches the context, and exposes the entire viewport as a single static image. The alternative marks renderer.domElement as aria-hidden and maintains a separate visually hidden DOM subtree that mirrors scene state, trading duplication for dynamic, granular announcements.
Because three.js cannot declare which representation is authoritative, teams must choose per view whether the canvas is decorative, a labeled image, or a hidden surface backed by a parallel accessible region. Constraints include the risk of flooding assistive technology if a live region updates on every animation frame, and the fact that canvas fallback content is only shown when the element is unsupported, not as a screen-reader description in supporting browsers.
Should the canvas be exposed as a single labeled image when scene state is stable and object identity is irrelevant? Or should it be hidden while a throttled DOM mirror announces meaningful state changes, accepting the maintenance cost of duplicated state? How can teams determine, without library-level guidance, which representation remains authoritative for a given view?
A thoughtful contribution can make all the difference. Be the first to share one.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.