Making canvas content accessible

[This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation]

Because HTML5 doesn't include a way to expose canvas content to accessibility, you should use the CANVAS element sparingly in an accessible app. If you must use CANVAS, we recommend that you use Accessible Rich Internet Applications (ARIA) attributes to describe the nature, behavior, and properties of the canvas. The most straightforward case is when the CANVAS element directly corresponds to a single ARIA role.

<!-- Canvas exposed as an image element. -->
<canvas id="example" width="260" height="200" role="img" >Circles</canvas>

<!-- Canvas exposed as a button element -->
<canvas id="roundButton" width="50" height="50"
    tabindex="0" role="button" aria-label="Round"
    onmousedown="..." onmouseup="..." onclick="..." onkeydown="..." onkeyup="...">

Typically, the CANVAS element is dynamic and you need to do more work to make app scenarios accessible. In particular, you need to implement a parallel Document Object Model (DOM) representation that is dynamically tied to the canvas content and stays in sync with it.

In this example, the ARIA grid role provides an alternate representation of a canvas that draws a chess board. The elements in the grid must be maintained from JavaScript as the canvas content changes.

<!-- A canvas that draws a chessboard has an alternate grid representation. -->
<canvas id="chessBoardCanvas" width="300" height="300" role="grid" 
      tabindex="0" aria-label="Chess board" aria-activedescendant="a8">
    <div id="r8" role="row" aria-label="Row 8">
        <div id="a8" role="gridcell" aria-label="a8">
            <div role="img">black rook</div>
        <div id="b8" role="gridcell" aria-label="b8">
            <div role="img">black knight</div>
    <div id="r7" role="row" aria-label="Row 7">
        <div id="a7" role="gridcell" aria-label="a7">
            <div role="img">black pawn</div>
    <div id="r6" role="row" aria-label="Row 6">
        <div id="a6" role="gridcell" aria-label="a6"></div>
        <div id="b6" role="gridcell" aria-label="b6"></div>

As you design your app, keep in mind that the accessibility solution described here has some limitations. While it ensures the correct UI tree structure, the parallel Document Object Model (DOM) representation is not accessible in all scenarios. For example, hovering over the canvas with the mouse or touch returns only the container DIV element and not the subelements that represent canvas content.

Note The XAML Canvas element is just a Panel with absolute positioning. It doesn't have the issues described here with HTML Canvas. Its children can be read as items and will appear in a Microsoft UI Automation view if they're relevant to app logical structure (Canvas itself is a visual element for layout only and doesn't convey app structure info, so you don't typically see it in a UI Automation view).

Implementing accessibility for particular content types