html5 shadow dom,HTML5 Canvas and the Canvas Shadow DOM

HTML5 Canvas and the Canvas Shadow DOM

05/11/2015

5 minutes to read

In this article

The canvas shadow DOM enables you to provide code behind a canvas element for better user interaction and accessibility.

What is the Canvas Shadow DOM?

HTML5 Canvas provides a rich drawing surface that can be used for graphics, images, and even video display that can be manipulated with a collection of properties and methods. However, canvas is a strictly visual medium, which makes it difficult for screen readers and assistive technology to understand, without a little help.

The canvas shadow DOM is a sub version of the Document Object Model (DOM) in Windows Internet Explorer that offers a way to create an alternate interactive experience for assistive technology, as well as for browsers that don’t support Canvas. When you use the canvas tag, it is common to put some fallback code between the two canvas tags for browsers that lack canvas support. For example:

Canvas not supported example

HTML5 canvas support is required for a fully interactive experience, so here’s this:

some cool stuff

In a browser that supports canvas, the user might see a JavaScript animated image. If canvas isn’t supported, the canvas tag is ignored and the static image is displayed. Through this technique, the canvas shadow DOM can do its magic.

Fallback content - is it there, or not?

The fallback content, in this case a message and image, are normally hidden if canvas is supported in the browser. However, the content is still alive and well, and can be read and interacted with by assistive technology devices, such as screen readers.

Unlike a distant cousin, the alt attribute, the code between the tags is its own sub-DOM tree for to assistive technology. In its simplest form, you can add text to replace the graphic. The text can include HTML structure, such as lists and tables, which are not available with the alt attribute. The next example puts an ordered list behind a canvas.

Canvas fall back example
The image here shows the future highway that will be:
  1. Connecting the east side of the mountain to the west side
  2. Providing four wide lanes for traffic
  3. Adding a bike lane

You can also add fully interactive code, so if something changes in the canvas element, it can be reflected in the canvas DOM. Keeping the two in sync however, is the developer’s responsibility, but if done right, can be very powerful. The following is a simple example of using the same data and mirroring it either in a canvas based fan control, or a list. Most of the JavaScript code in the example is building a graphic fan control. Between the canvas tags is a simple list that displays the same information.

Canvas and ARIA fan speed control

// Drawing & UI handler code should get the state from the actual controls

// or, the author has to do some work to sync controls & variables

function GetSpeed() {

if (document.getElementById("r0").getAttribute("aria-checked") == "true") return 0;

if (document.getElementById("r1").getAttribute("aria-checked") == "true") return 1;

if (document.getElementById("r2").getAttribute("aria-checked") == "true") return 2;

if (document.getElementById("r3").getAttribute("aria-checked") == "true") return 3;

}

var scaled = false;

// Draw the custom control

function Draw(focus) {

var canvas = document.getElementById("canvaselement");

if (canvas.getContext) {

var fanspeed = GetSpeed();

var ctx = canvas.getContext('2d');

ctx.clearRect(0, 0, 100, 100);

if (scaled == false) {

ctx.scale(3, 3);

scaled = true;

}

// Draw control

ctx.beginPath();

ctx.strokeStyle = "rgb(0, 0, 0)";

ctx.arc(50, 50, 20, 0, 2 * Math.PI, false);

ctx.stroke();

// Draw control text

ctx.fillText("Fan speed", 2, 12);

ctx.fillText("Off", 43, 80);

ctx.fillText("Low", 8, 53);

ctx.fillText("Medium", 32, 26);

ctx.fillText("High", 74, 53);

//Draw selected setting

var x;

var y;

switch (fanspeed) {

case 0:

x = 50;

y = 62;

break;

case 1:

x = 38;

y = 50;

break;

case 2:

x = 50;

y = 38;

break;

case 3:

x = 62;

y = 50;

break;

}

ctx.beginPath();

ctx.strokeStyle = "rgb(255, 0, 0)";

ctx.arc(x, y, 4, 0, 2 * Math.PI, false);

ctx.stroke();

}

}

// The UI handler for the custom control

function Cycle(direction) {

var fanspeed = GetSpeed();

var o = "r" + fanspeed; //old radio button to clear

var ox = document.getElementById(o);

ox.setAttribute("aria-checked", "false");

ox.setAttribute("tabindex", "-1");

if (direction == "down") {

fanspeed = fanspeed - 1;

if (fanspeed == -1) fanspeed = 3;

}

else {

fanspeed = fanspeed + 1;

if (fanspeed == 4) fanspeed = 0;

}

var r = "r" + fanspeed; //radio button to set

var rx = document.getElementById(r)

rx.setAttribute("aria-checked", "true");

rx.setAttribute("tabindex", "0");

rx.focus();

Draw(true);

}

function Keys(event) {

var key = event.keyCode;

if (key == 37 || key == 40) {

Cycle("down");

}

else if (key == 38 || key == 39 || key == 32 || key == 13) {

Cycle("up");

}

//else do nothing

}

Fan speed
Fan Speed: Off
Fan Speed: Low
Fan Speed: Medium
Fan Speed: High

In this example when canvas isn’t supported it shows a table that is driven by the same data that drives the canvas fan control. In a screen reader, even if canvas is supported, the table can be read. To test this yourself, open F12 developer tools, and change the Document Mode to something other than Windows Internet Explorer 9 or Internet Explorer 10.

A browser that supports canvas will see this graphic:

8c67aaabd11e1f171c607fc3f02448fb.png

A browser that doesn't support canvas, or a screen reader will "see" this:

32a435ad5f1645ba14d1562136435802.png

Canvas Shadow DOM isn't just for accessibility

The canvas shadow DOM can also provide better interactivity. For example, if you render a stock chart from data in a table contained in the canvas DOM, you can use the keyboard to make updates. Using forms and fields, such as radio buttons, your interaction from the keyboard can be reflected back through the canvas graphic for sighted users with supported browsers, and the form and buttons otherwise.

Because the canvas shadow DOM can contain any HTML elements, you can store and access interactive data based on the state of elements, such as buttons and input tags. Even though elements might be hidden from view to a sighted person when canvas is supported, JavaScript can still access the elements.

Canvas graphics and the canvas shadow DOM are good for single controls, and can provide a great experience for the user and developer alike. However, the app can only get focus and a bounding rectangle for the whole canvas, not sections of it. This means that keyboard focus goes to a point at canvas coordinates 0,0. This will affect anything that depends on the focus, like screen magnifiers. If your app requires more complex interactive graphic experiences, you might want to look at SVG and ARIA markup for accessibility.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值