HTML & CSS
Article

Canvas vs. SVG: Choosing the Right Tool for the Job

By Maria Antonietta Perna

Following the publication of Introduction to jCanvas: jQuery Meets HTML5 Canvas on SitePoint, a thread of great comments initiated by Craig Buckler has sprung up around a core topic: are there any use-cases for preferring HTML5 Canvas over SVG?

Both are standards-based HTML5 technologies you can use to create amazing graphics and visual experiences. But should it matter which one you use in your project?

At one point, Craig’s comment goes straight to the heart of the Canvas vs. SVG debate, as he writes:

One benefit of canvas is that it doesn’t have a DOM! It allows you to animate thousands of objects without that overhead – which is ideal for games.

Following Craig’s trails, I’m going to do my best to explore the question outlined above and discuss key factors to consider when opting for one technology over the other.

First, let’s spend a few words introducing HTML5 Canvas and SVG.

What is HTML5 Canvas?

Here’s how the WHATWG specification introduces the canvas element:

The canvas element provides scripts with a resolution-dependent bitmap canvas, which can be used for rendering graphs, game graphics, art, or other visual images on the fly.

In other words, the <canvas> tag exposes a surface where you can create and manipulate rasterized images pixel by pixel using a JavaScript programmable interface.

Here’s a basic code sample.

The HTML:

<canvas id="myCanvas" width="800" height="800"></canvas>

The JavaScript:

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
context.fillStyle = '#c00';
context.fillRect(10, 10, 100, 100);

You can take advantage of the HTML5 Canvas API methods and properties by getting a reference to the 2D context object. In the example above, I have drawn a simple red square, 100 x 100 pixels in size, placed 10px from the left and 10px from the top of the <canvas> drawing surface.

Red square drawn using HTML5 Canvas

Being resolution-dependent, images you create on <canvas> may lose quality when enlarged or displayed on retina screens.

Drawing simple shapes is just the tip of the iceberg. The HTML5 Canvas API allows you to draw arcs, paths, text, gradients, etc. You can also manipulate your images pixel by pixel. This means that you can replace one color with another in certain areas of the graphics, you can animate your drawings, even draw a video onto the canvas and change its appearance.

What is SVG?

SVG stands for Scalable Vector Graphics. According to the specification:

SVG is a language for describing two-dimensional graphics. As a standalone format or when mixed with other XML, it uses the XML syntax [XML10]. When mixed with HTML5, it uses the HTML5 syntax [HTML]. …

SVG drawings can be interactive and dynamic. Animations can be defined and triggered either declaratively (i.e., by embedding SVG animation elements in SVG content) or via scripting.

SVG is an XML file format designed to create vector graphics. Being scalable has the advantage, contrary to HTML5 Canvas-generated images, of letting you increase or decrease a vector image while maintaining its crispness and high quality.

Here’s the same red square I created with HTML5 Canvas, this time drawn using SVG:

<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 600 600">
  <desc>Red rectangle shape</desc>
  <rect x="10" y="10" width="100" height="100" fill="#c00"  />  
</svg>

You can do with SVG most of the stuff you can do with <canvas>, e.g., drawing shapes and paths, gradients, patterns, animation, etc. However, these two technologies work in fundamentally different ways. As it will become clearer in the following sections, this difference plays a significant part when you need to make a choice between <canvas> and SVG for your next project.

Immediate Mode and Retained Mode

It’s crucial to distinguish between something called immediate mode and retained mode. These are two different approaches to getting content to display in your browser.

The HTML5 Canvas API is an example of immediate mode: you, as the developer, need to work out the commands to draw objects, create and maintain the model or scene of what the final output should look like, and specify what needs to be updated. The browser’s Graphics API simply communicates your drawing commands to the browser, which then executes them.

SVG uses the retained approach, where you simply issue your drawing instructions of what you want to display on the screen, and the browser’s Graphics API creates an in-memory model or scene of the final output and translates it into drawing commands for your browser.

To go back to Craig’s comment, being an immediate graphics system, <canvas> hasn’t got a DOM, i.e., Document Object Model. With <canvas>, you draw your pixels and the system forgets all about them, thereby cutting down on the extra memory needed to maintain an internal model of your drawing. With SVG, each object you draw gets added to its internal model, which makes your life as a developer somewhat easier, but at some costs in terms of performance.

On the basis of the distinction between immediate and retained mode, as well as other specific characteristics of <canvas> and SVG respectively, it’s possible to outline some cases where using one technology over the other would better serve your project’s goals.

HTML5 Canvas and SVG Side by Side

The HTML5 Canvas specification clearly recommends that authors should not use the <canvas> element where they have other more suitable means available to them.

For instance, for a graphically rich <header> element, the best tools are HTML and CSS, not <canvas>. So, that’s a clear-cut example of when not to use <canvas>.

Now, we need to work out some possible scenarios where <canvas> would be appropriate and even preferable to SVG.

To this purpose, let’s go over a summary of the features specific to <canvas> and SVG respectively. This will help us understand what each of them has to offer as well as where their limitations lie.

What HTML5 Canvas Can Be Great For

To summarize, HTML5 Canvas is a resolution-dependent immediate drawing system that doesn’t maintain its own model. The last feature is key to this technology’s drawing capabilities being lightning-fast, which makes HTML5 Canvas great at performing the following tasks:

Ray Tracing

Ray tracing is a technique for creating 3D graphics. If you’re curious, here’s a raytracer application in action by Mark Webster.

Canvas Raytracer by Mark Webster

However, although HTML5 Canvas is definitely better suited to the task than SVG could ever be, it doesn’t necessarily follow that ray tracing is best executed on a <canvas> element. In fact, the strain on the CPU could be quite considerable, to the point that your browser could stop responding.

Drawing a significant number of objects on a small surface

Another example is a scenario where your application needs to draw a significant number of objects on a relatively small surface, e.g., non-interactive real time data visualizations like graphical representations of weather patterns.

Graphical representation of weather patterns with HTML5 CanvasThe above image is from this MSDN article, which was part of the research for this piece.

Pixel replacement in videos

As demonstrated in this HTML5 Doctor article, another example where canvas would be appropriate is when replacing a video background color with a different color, another scene, or image.

Replacing pixels in a video to convert it to grayscale on the fly using HTML5 Canvas

What HTML5 Canvas Is Not So Great For

On the other hand, there are a number of cases where <canvas> is not the best choice compared to SVG.

Scalability

Most scenarios where scalability is a plus are going to be better served using SVGs than <canvas>. High fidelity complex graphics like building and engineering diagrams, organizational charts, biological diagrams, etc., are examples of this.

When drawn using SVG, enlarging the images or printing them preserves all the details to a high level of quality. You can also generate these documents from a database, which makes the XML format of SVG highly suited to the task. Also, these graphics are often interactive. Think about seat maps when you’re booking your plane ticket online as an example, which makes them a great use-case for a retained graphics system like SVG.

Accessibility

If accessibility is crucial to your application, using <canvas> is generally not recommended. What you draw on the canvas surface is just a bunch of pixels, which can’t be read or interpreted by assistive technologies or search engine bots. This is another area where SVG is preferable: SVG is just XML, which makes it readable by both humans and machines.

No reliance on JavaScript

If you don’t want to use JavaScript in your application, then <canvas> is not your best friend. In fact, the only way you can work with the <canvas> element is with JavaScript. Conversely, you can draw SVG graphics using a standard vector editing program like Adobe Illustrator or Inkscape, and you can use pure CSS to can control its appearance and perform attractive animations.

Combining HTML5 Canvas and SVG for Advanced Scenarios

There are cases where your application can get the best of both worlds by combining HTML5 Canvas and SVG. For instance, a <canvas>-based game could implement sprites from SVG images generated by a vector editing program, to take advantage of the scalability and reduced download size compared to a PNG image; or a paint program could have its user interface designed using SVG, with an embedded <canvas>element, which can be used for drawing.

Resources

If you’d like to delve deeper into this topic, the following resources are a great read:

Conclusion

In this article, I’ve explored some key features of both HTML5 Canvas and SVG in view of providing some guidance as to which technology could be more suited to particular tasks over the other.

The end result, in my view, is that there aren’t any hard and fast rules for when it’s best to use <canvas> instead of SVG. However, the distinction between immediate and retained mode gives us some clues as to which scenarios could benefit from <canvas> over SVG and vice versa.

I want to close with a really concrete tip to help you decide between HTML5 Canvas and SVG:

… if you need to paint pixels to the screen and have no concerns about the ability to retrieve and modify your shapes, canvas is probably the better choice. If, on the other hand, you need to be able to access and change specific aspects of your graphics, SVG might be more appropriate.
HTML5 & CSS3 For the Real World, 2nd Edition

HTML5 Canvas or SVG, which one do you go for?

To all the HTML5 Canvas and SVG ninjas out there, come along and share your experience with the community, it’d be awesome to hear from you!

  • Craig Buckler

    The sub-DOM is a fallback. You must keep both the canvas and the sub-DOM in sync whenever you change anything. It’ll aid accessibility but will not help search-engine indexing.

    There may be cases where it’s useful but SVG is a simpler solution.

    • http://memmie.lenglet.name Mem’s

      You should see canvas as an augmented version of its sub-DOM, like an alternative.
      Accessibility and SEO are quite similar. It relies on semantics and structure to help people or machine find info.
      Search engines that don’t support JS or the canvas element will just ignore it and will index content inside it. If JS and canvas are supported, children of the canvas (alternative content) is still accessible (to the search engine). If search engine use machine learning / AI, the alt. content will be used to label the canvas graphical content

      • Craig Buckler

        I understand the concept but I just find it cumbersome compared to SVG or a standard image. Canvas is great for fast animations but not accessibility or indexing. If you attempt to “fix” that, you’re possibly using the wrong technology.

        Search engines cannot index canvas pixels. It’s a programmable image which can rapidly change over time so it’d be largely pointless to attempt it.

        If the canvas is changing/animating, the server-generated sub-DOM wouldn’t necessarily describe what’s occurred. You could update the sub-DOM to aid accessibility but makes the process slower and more awkward to develop. SVG may be more practical since that already provides a DOM and some level of accessibility.

        If you’re not modifying the canvas after the initial generation, the server-generated sub-DOM is fine because it describes what’s been displayed. But if you’re not changing the canvas, isn’t a static image more suitable?

  • jedbt

    Just a note that there are no units specified in HTML dimensions (it’s pixels only):

    • LouisLazaris

      Haha, nice catch. Yeah, that was just a momentary lapse on Maria’s part, and mine (I edited the article).

  • http://Phi.Lho.free.fr/ Philippe Lhoste

    Good article.
    Note that SVG has filters which can be used to change color, to blur images, etc.
    SVG is good for accessibility, indeed, and as a side effect, it is also good for QA! Ie. Quality Assurance, the people in charge of testing our application from the user point of view.
    It is easier to check if there is a specific text at a given id / class in a SVG rendering than checking a static, monolithic image…
    That’s (also) why we chose our chart library (Highcharts) and graph library (jsPlumb). Beside the fact they are good! ;-)

  • http://egov.se Christian Svaetichin Paulsen

    So I assume there is no way of forcing a retina picture @2x to render correctly in a canvas?

Recommended

Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in Front-end, once a week, for free.