A WebGL canvas is a black box to assistive technology. Screen readers see an image element with no content. Keyboard navigation has no targets. The entire interface is invisible to anyone not using a mouse and a monitor.
The fundamental constraint: The HTML canvas element renders pixels. Once rendered, the content has no semantic structure. A screen reader cannot identify that there are 500 data points, that one is selected, or that clicking a cluster shows details. No DOM nodes, no ARIA attributes, no focus targets.
This does not mean 3D interfaces cannot be accessible. It means accessibility must be designed deliberately. The 3D visualisation provides one representation of the data. Alternative representations (tables, summaries, keyboard-navigable controls) provide others. The combination serves all users.
Accessibility Simulator
A Three.js 3D scatter plot with four data categories, each encoded by both shape and colour. Toggle the modes to experience how accessibility features change a real WebGL scene. "Keyboard Mode" enables arrow key navigation with screen reader output. "Deuteranopia" simulates red-green colour blindness.
The Naive Approach
The typical approach to 3D accessibility is to do nothing meaningful. This excludes users with visual impairments, motor impairments, vestibular disorders, and anyone using assistive technology.
Alternative Data Representations
The most impactful accessibility measure: provide the same data in a non-visual format. The 3D visualisation and the alternative representation should be linked, so that interaction with one updates the other.
-
Data table A standard HTML table with the same data shown in the 3D visualisation. Sortable, filterable, searchable. Screen readers navigate tables natively. Selecting a row highlights the corresponding point in the 3D view; selecting a point scrolls the table to the corresponding row.
-
Text summary A generated description of key insights. "Three distinct clusters. The largest cluster (342 points) is centred at high revenue, high engagement. An outlier group of 12 points shows high revenue but low engagement." Helps screen reader users understand the overall pattern without navigating individual points.
-
Export Let users download the data as CSV, JSON, or a format compatible with their preferred analysis tools. Users with specialised software may have better tools for exploring the data than anything a browser provides.
Both representations show the same data. Users choose the one that works for them. The table is not a lesser fallback; it is a first-class interface for users who need or prefer it.
Keyboard Navigation
Every interactive action must be achievable by keyboard. This requires explicit implementation because the canvas provides no built-in focus management.
Camera Controls
Arrow keys or WASD for rotation/orbit. Plus/minus or Page Up/Page Down for zoom. Home to reset camera to default position. These mirror standard 3D application conventions.
Object Navigation
Tab or arrow keys to cycle through selectable objects. The "focus" moves to the next object, which is highlighted visually and announced to screen readers via ARIA live regions.
Selection and Action
Enter or Space to select the focused object (equivalent to click). Escape to deselect. These match standard keyboard interaction patterns.
ARIA Live Region Announcements
A visually hidden div with aria-live="polite" announces the currently focused object. When keyboard focus moves to a data point, update the text: "Data point: Revenue 45,000, Engagement 78, Churn risk low." Screen readers read this automatically.
Screen Reader Integration
Two approaches exist, depending on whether the application uses React Three Fiber or vanilla Three.js. Both create an invisible HTML structure that mirrors the 3D scene. Sighted users see the 3D scene. Screen reader users hear the same content described in text.
react-three-a11y (R3F)
For React Three Fiber applications, this library provides accessible descriptions for 3D objects. It creates an invisible HTML overlay with focusable elements positioned to match 3D objects. Each element has ARIA attributes describing the 3D content.
Manual Approach (Vanilla Three.js)
Create an offscreen HTML element for each interactive 3D object. Position it using the same projection used for CSS2D labels (but visually hidden). Give it tabindex="0", an aria-label, and click/keypress handlers that mirror the 3D interaction.
The manual approach is verbose but effective. The screen reader navigates a hidden HTML structure that mirrors the 3D scene. The implementation effort is proportional to the number of interactive objects, not the visual complexity.
Motion Sensitivity
Some users experience discomfort, dizziness, or nausea from on-screen motion. The prefers-reduced-motion CSS media query indicates when a user has requested reduced motion at the OS level.
Detection: window.matchMedia('(prefers-reduced-motion: reduce)').matches returns true when the user has requested reduced motion. Check on initialisation and listen for changes. All feature widgets on this site check this preference.
Colour and Visual Encoding
Colour vision deficiency affects approximately 8% of male and 0.5% of female users. Never use colour as the sole channel for information.
WCAG Compliance
Web Content Accessibility Guidelines (WCAG) 2.1 apply to Three.js content. Full compliance for 3D content is uncommon. But partial compliance covering the most impactful requirements significantly improves the experience for affected users.
| WCAG Criterion | Requirement | Three.js Implementation |
|---|---|---|
| 1.1.1 Non-text Content | Text alternative for canvas | Descriptive aria-label + full data table alternative |
| 1.4.1 Use of Colour | Colour not sole differentiator | Shape + pattern + label paired with colour |
| 1.4.3 Contrast | Sufficient foreground/background contrast | Test data points against scene background |
| 2.1.1 Keyboard | All functionality via keyboard | Arrow/Tab navigation + Enter/Escape + ARIA live |
| 2.3.1 Three Flashes | No content flashes 3+ times/second | Audit animations and state transitions |
| 2.5.1 Pointer Gestures | Single-pointer alternatives exist | Keyboard + button alternatives for pinch zoom |
| 4.1.2 Name, Role, Value | Interactive elements have accessible names | Hidden HTML overlay with ARIA attributes |
With vs Without Accessibility
The same 3D scatter plot, experienced differently depending on whether accessibility has been implemented.
| Experience | Without Accessibility | With Accessibility |
|---|---|---|
| Screen reader | "Image, 3D visualisation" | Full data table + summary + point-by-point navigation |
| Keyboard user | Cannot interact at all | Tab through points, arrow keys for camera, Enter to select |
| Colour blind user | Categories indistinguishable | Shape + label encoding alongside colour |
| Motion sensitive | Nausea from auto-rotation | Static scene, instant camera moves, manual toggle |
The Business Link
Accessibility is a legal requirement in many jurisdictions (ADA in the US, EAA in the EU, AODA in Ontario, DDA in the UK). Non-compliance creates legal exposure. Beyond compliance, accessible 3D interfaces are better interfaces for everyone.
Build it in from the start. Keyboard navigation benefits power users. Data tables benefit anyone who needs precise values. Motion controls benefit anyone on a bumpy train. Colour independence benefits anyone viewing a projected screen in a bright room. The cost is design-time decisions and a modest amount of additional HTML. The cost of retrofitting into an existing 3D application is significantly higher.
Build Accessible 3D Interfaces
We build Three.js applications that work for all users. Keyboard navigation, screen reader support, motion sensitivity, and colour independence: designed in from the beginning, not bolted on later.
Let's talk about your accessibility requirements →