figma

Building Accessibility Into a Canvas-Based Product | Figma Blog (opens in new tab)

Figma’s canvas-based rendering enables performance features such as infinite zoom and real-time collaboration, but it removes the browser’s built-in accessibility support. To restore that support, Figma built a synchronized “Mirror DOM” that represents the canvas in ordinary DOM elements for screen readers and keyboard users. The system combines an internal accessibility tree, React-rendered mirror elements, bidirectional selection syncing, and announcements for non-navigational changes.

Why Canvas Requires a Different Accessibility Strategy

  • Figma renders designs on a canvas rather than with traditional HTML and DOM.
  • This improves performance but leaves the browser’s accessibility tree nearly empty.
  • Unlike a conventional web app with semantic elements such as <button>, <p>, and <img>, Figma’s canvas effectively has only one focus-holding <input>.
  • Without additional work, screen readers cannot navigate or meaningfully interpret the layers in a Figma file.

Synthesizing an Accessibility Tree

  • Browsers normally derive an accessibility tree from the DOM, semantic HTML, ARIA attributes, and computed state.
  • Figma created its own internal accessibility tree to provide equivalent non-visual information for each design layer.
  • Each layer receives an accessible summary describing the role and content a screen reader should announce.
  • Summaries vary according to context:
    • In prototypes, editing-related layers can be omitted, while text and interactive roles are preserved for viewers.
    • In editing mode, structures such as autolayout frames need to remain available.
  • The tree is flattened by removing omitted nodes and connecting their relevant descendants.
  • Figma builds the tree initially, then applies surgical updates as documents change instead of rebuilding everything.

Rendering the Mirror DOM

  • A recursive React component converts the internal accessibility tree into DOM elements.
  • Each component subscribes to accessibility data for one design layer and renders its role, label, and children.
  • React’s incremental updates help keep DOM changes minimal as the design changes.
  • The resulting elements are invisible to sighted users but available to assistive technologies.

Synchronizing Canvas and Screen Reader Interaction

  • Figma maintains bidirectional synchronization between the visual canvas and the Mirror DOM.
  • Selecting a layer on the canvas moves focus to the corresponding DOM element.
  • When a screen reader user navigates the Mirror DOM, Figma updates the canvas selection accordingly.
  • This connects non-visual navigation with the editor’s visual state.

Announcing Changes

  • A separate announcement system communicates changes that are not primarily navigational.
  • It reports actions such as nudging objects, switching tools, and other updates that would normally be apparent visually.
  • Together with the Mirror DOM, these announcements help screen reader users understand both the document structure and ongoing editor activity.

Figma’s approach shows that accessibility can be rebuilt for canvas applications by maintaining a semantic representation alongside the rendering layer. Applications that prioritize canvas performance should provide a synchronized accessibility model rather than relying on the canvas itself to expose meaning to assistive technologies.