Graphics Canvas vs SVG
Canvas and SVG both let you draw shapes and graphics in the browser, but they work in opposite ways — one paints pixels immediately and forgets them, the other keeps every shape alive as an element you can query, style, and listen to.
Two Opposite Models for Drawing in the Browser
Both canvas and SVG can put shapes, paths, and images on screen, and on the surface a circle drawn in either can look identical. The difference is what happens after you draw it — and that's the single most important thing to understand before choosing between them. (This lesson deliberately skips their detailed syntax; see the dedicated Canvas and SVG tutorials on this site for that.)
Canvas: An Immediate-Mode Pixel Surface
Canvas gives you a blank bitmap and a set of drawing commands — draw this arc, fill this rectangle, paint this image. The moment a command runs, it's converted straight to pixels; the canvas has no memory of 'a circle' having been drawn, only of the pixels that resulted. That means animating anything requires clearing the canvas and redrawing the entire scene on every frame, and it means there's no built-in way to know which shape a user clicked — you have to manually compare the click coordinates against your own record of where each shape was drawn.
SVG: A Retained-Mode Scene Graph
SVG shapes are ordinary elements in the page's DOM — a circle or path is a real node the browser keeps around, the same way it keeps around a div. Because each shape is an addressable element, you can attach a standard event listener directly to it, style it with CSS (including hover states and transitions), and change it later just by updating an attribute — the browser handles repainting automatically.
Example
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script>
// Canvas: paint pixels, then the shape is forgotten
ctx.beginPath();
ctx.arc(50, 50, 20, 0, Math.PI * 2);
ctx.fill();
// clicking it does nothing on its own — you'd test coordinates yourself
// SVG: the shape is a living element
const circle = document.querySelector('circle');
circle.addEventListener('click', () => console.log('clicked!'));
</script>
</body>
</html>When Canvas Wins
- Particle systems or simulations with thousands of moving points, where creating that many DOM elements would be far too slow.
- Pixel-level work — image filters, video frame processing, procedural textures.
- Games that redraw a full frame many times a second anyway.
When SVG Wins
- Diagrams, org charts, or icons where individual pieces need their own hover state, tooltip, or click handler.
- Data visualizations with a reasonable number of shapes that benefit from being real, stylable elements.
- Anything that must stay crisp at unknown or changing sizes, like an icon used at 16px and 200px.