HTML5 Canvas and the DOM – explain ?

I’ve seen a few questions on The ‘Net around how the HTML5 canvas fits into the DOM and whether canvas content can be styled via CSS – here’s my explanation. I also mention a few libraries and why you would want to use them…

The HTML5 canvas element arrived with HTML5 (Wikipedia). The canvas is great for building advertisement displays, games, draw / paint apps, web-to-print, visualisations, charts, in fact anything that requires dynamic pixel-perfect renditions of your designs.

In HTML terms, the canvas element is just another element, meaning you can style it as per any other element like this…

<!DOCTYPE html>
<html>
<body>

<canvas id="myCanvas" width="200" height="100" style="border:1px solid #000000;">
</canvas>

</body>
</html>

So that means element position, visibility, size, and border effects. The content of the element is out of bounds from CSS styling. To do anything to the content displayed on the canvas, you need to use the canvas API (mozzilla.org canvas API tutorial) – see example below.

Which produces the following output…

Example HTML5 canvas output

Which you can not style via CSS. If you open the developer tools and inspect the page in the above demo (shown below) you will see that the canvas element is not expandable – there is literally no way, using CSS or DOM selectors, to reach inside of it and access the two rectangles or text that we see it displaying.

Canvas libraries – why use them ?

A quick look at the canvas API commands should inform you that writing code at that level is laborious, meaning it will take much time to produce anything important, what you produce will be complex, probably susceptible to coding errors, and costly to support.

The good news is that there are many ‘libraries’ that wrap the canvas API behind a higher-level model and API structure. The majority are free and therefore relying heavily upon them for commercial projects represents a risk – do some sleuthing and make a judgement on the level of that risk.

I have used both goJS and Konva in commercial projects.

One possible driver toward using the raw canvas API would be a concern about performance since often a badly written library can impact performance negatively and no one wants to earn a reputation for making a slow or jerky game. However, the library writers are aware of this – follow their advice on coding for performance and you will not be disappointed.

Summary

We have learned that the HTML5 canvas element can be styles superficially via CSS, but that the contents cannot. We’ve also got some pointers to some libraries that we can use to help accelerate development and produce more robust and supportable code.

Foot note about SVG

SVG (Scalable Vector Graphics – see mozilla intro) is a vector graphics definition format that pre-dates the HTML5 canvas. You can embed SVG drawing commands directly into HTML and you CAN access the SVG drawing elements with DOM manipulation commands, meaning that whilst you can’t style the SVG drawing elements, you can at least move, hide or ease them.

SVG can also be handed into the canvas element to make entire canvas drawings or individual components within the canvas. However, you cannot access these SVG elements via DOM manipulation commands after they are absorbed into the canvas.

In my experience I have tended to use SVG either as a means to draw a complex image component into a canvas, and for a few edge cases where SVG got me round an issue. Mostly in my work with Konva and goJS I find myself using their canvas API’s, meaning reverting to SVG is not an everyday need.

Thanks for reading.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: