Accessible Publishing Knowledge Base

Canvas

Summary

...

Techniques

The canvas element provides a two-dimensional drawing surface, which introduces the same accessibility issues as occur with images. That the element can be used for static and dynamic images makes it similar in nature to SVG, and further complicates access.

When using the element to draw static two-dimensional images, consider wrapping the element as a figure and embedding a description in the caption.

If the element is used to draw bar graphs, pie charts and similar data representations, also consider making that data available in a more accessible form (e.g., as a table).

Note

The HTML specification requires that equivalent fallback content be provided when using the canvas element. Although this content can be embedded in the canvas element itself, doing so may interfere with other accessibility requirements (e.g., a description should not be included in the canvas if the canvas element already contains shadow DOM elements for scripting).

Before scripting content, consider the impact it will have on the user experience. If the information that you draw is critical to the comprehension of the book, ensure that scripting the element is only an enhancement of that information (i.e., do not lock it up in a requirement that scripting be enabled).

Ideally, when scripting the canvas element the element should remain accessible. Since the element is just a bitmap image, current accessibility work is aimed at providing a shadow DOM that can be manipulated. To this end, developers can embed accessible elements (using WAI-ARIA states and properties) inside the canvas element to represent what is being drawn, thereby allowing assistive technologies to interact with the accessible elements in similar fashion to how someone would visually interact with the display.

Early experimental support is only just beginning to appear, however, so this page is subject to change.

Examples

Example 1 — Wrapping a canvas in a figure
<figure>
   <figcaption>
     <span class="caption">Figure 1 — Sales 
     of tablets by manufacturer: Sorny 45%, 
     MagnetBox 25%, Panaphonics 30%</span>
   </figcaption>
   <canvas id="piechart" width="400" height="400"></canvas>
</figure>
<script>
<![CDATA[
   function drawPie() {
   
     var mfctr = new Array();
        mfctr[0] = new Array();
        mfctr[0].name = 'Sorny';
        mfctr[0].pct = 45;
        mfctr[0].color = 'rgb(0,0,255)';
        mfctr[1] = new Array();
        mfctr[1].name = 'MagnetBox';
        mfctr[1].pct = 25;
        mfctr[1].color = 'rgb(0,255,0)';
        mfctr[2] = new Array();
        mfctr[2].name = 'Panaphonics';
        mfctr[2].pct = 30;
        mfctr[2].color = 'rgb(255,0,0)';
     
     var canvas = document.getElementById('piechart');
     
     var context = canvas.getContext('2d');
        context.clearRect(0, 0, canvas.width, canvas.height);
     
     var lastpos = 0;
     var labelpos = 325;
     
     for (var i = 0; i < mfctr.length; i++) {
       
       var m = mfctr[i];
       
       context.fillStyle = m.color;
       context.beginPath();
       context.moveTo(200,150);
       context.arc(200,150,150,lastpos,lastpos+(Math.PI*2*(m.pct/100)),false);
       context.lineTo(200,150);
       context.fill();
       
       context.strokeStyle = 'rgb(0,0,0)';
       context.stroke();
       
       context.fillStyle = m.color;
       context.font = "16pt Arial";
       
       var text = m.name;
       var offset = context.measureText(text);
       context.fillText(text, 0, labelpos);
       
       var pctlabel = ' -- ' + m.pct + '%';
       
       context.fillStyle = 'rgb(0,0,0)';
       context.fillText(pctlabel, offset.width, labelpos);
       
       labelpos += 35;
       lastpos += Math.PI*2*(m.pct/100);
     }
   }
   
   drawPie();
]]>
</script>

Following is a working demo of this code:

Figure 1 — Sales of tablets by manufacturer: Sorny 45%, MagnetBox 25%, Panaphonics 30%
  • Sorny 45%
  • MagnetBox 25%
  • Panaphonics 30%

References