Canvas Rendering Meets Assistive Technology

Figma’s editor works more like a video game than a standard web page: the canvas takes over rendering from the browser to deliver performance features such as infinite zoom and real-time multiplayer. That approach means the app does not use traditional HTML and DOM elements to draw the interface, which in turn means none of the default browser accessibility features apply to the canvas itself. In a typical web app, a component might map to a <button>, <p>, or <img> element; in Figma, the canvas is a single <input> element that holds focus no matter how many layers exist in the file. From the browser's perspective, the accessibility tree for a design is essentially empty.

To restore those capabilities, the Figma engineering team built a system that synthesizes the missing DOM. The approach consists of four collaborating parts: an internal accessibility tree that caches data about design layers, a React component that renders a "Mirror DOM," a bidirectional system for synchronizing canvas selection with keyboard focus, and a live-region-based announcement system for non-navigational changes.

Building the Mirror DOM

Browser engines create an accessibility tree from a document's DOM, semantic HTML, and ARIA attributes, which assistive technologies then consult to perform actions like "go to next form field." Since Figma does not draw its designs with HTML, the team had to construct the data source themselves.

The internal accessibility tree

Figma creates an internal accessibility tree that stores the non-visual information a screen reader needs for every layer in the scenegraph. Each layer gets an "accessible summary" that is read aloud by the assistive technology. That summary depends on the application context: in prototype mode, editing features are omitted and only content is emulated—text fields show their text, clickable items expose a button role. In editing mode, autolayout frames (which prototypes exclude) need to be navigable.

Layer summaries are generated one at a time, then the team walks the tree top to bottom, flattening any omitted nodes. The tree is fully constructed on document load, but subsequent edits trigger surgical updates instead of full rebuilds to avoid costly re-renders.

Rendering the Mirror DOM

With the internal accessibility tree in place, a recursive React component renders the corresponding DOM. Each instance of the component subscribes to changes for one specific design layer, and because the accessibility tree updates incrementally, React can keep DOM mutations minimal as well.

One non-obvious decision: the Mirror DOM is not visually hidden with standard techniques. Typical accessible-hidden styling removes content from page layout, but Figma needs the Mirror DOM elements to be positioned. Spatial layout is core to a design document's meaning, and position data feeds multiple assistive tools: screen magnifiers pan to keep focused elements in view, screen readers render a high-contrast outline for partially sighted users, and voice-control tools display on-screen cues.

Positioning is computed with affine transforms, the mechanisms Figma already uses to track offset, scaling, and rotation for every layer. Since arbitrary sequences of affine transforms can be concatenated into one, those transforms can produce a single CSS representation that includes any skews or rotations.

Synchronizing Selection, Focus, and Announcements

Focus and selection are separate concepts. Focus is a system keyboard property indicating the element being interacted with; selection is what the user has picked for an action. In the Figma canvas, pressing Tab changes the selected node without moving the system focus, which made the entire canvas look like one navigation target to screen readers.

The team built a two-way sync into the Mirror DOM so these stay in lockstep. When a node is clicked on the canvas, the corresponding DOM element receives focus for the screen reader; when a screen reader moves the focus—including with controls like the VoiceOver rotor—the visible selection highlights update in turn.

The accessibility tree and Mirror DOM expose a document's contents to assistive technologies, but editing requires confirming a user's actions back to them. Nudging an element, for instance, is visually obvious to a sighted user but silent otherwise. The implementation relies on ARIA live regions for this job. Live region markup is added to every toast announcement in the product, plus invisible announcements for events that would be noisy visual clutter—most users don't need a toast popup confirming every single arrow-key nudge, but such confirmations matter to screen reader users.

The system also handles coalescing: when multiple events of the same category happen close together, they merge. Five consecutive one-pixel nudges produce a single announcement reading "Moved five pixels" rather than repeating "Moved one pixel" five times.

Rollout and Roadmap

The accessibility work at Figma developed through feedback from assistive technology users gathered via a partnership with Fable. Accessibility launched in the prototype viewer in 2022, FigJam followed in 2023, and the years since added more extensive coverage: the "Adapt content for screen readers" setting rolled out across Design, Dev Mode, and Slides, alongside the first version of canvas keyboard controls, an enhanced contrast mode, and more than 15 additional accessibility-focused improvements.

Accessibility checks are now integrated into the feature development pipeline at Figma. New features are reviewed for accessibility support, and the team is investing in internal tooling—including an AI agent with Figma-specific context and guidance for the design systems team—to scale that perspective across the company.

For people building their own products in Figma, the company has also shipped designer-facing accessibility features. The color picker can flag whether a color combination meets accessibility guidelines, and the Rename Layers feature passes an explicit visible name to screen readers. A newer addition called Check Designs compares a design against its design system and flags deviations; among its checks is low contrast, for which it suggests WCAG 2.0 AA- or AAA-compliant colors before the work reaches engineering.