Both Canvas and SVG are used to draw graphics on the web, but they work in very different ways. Canvas is a bitmap you paint with JavaScript – great for fast-changing scenes such as games, particles, or big animated charts. SVG is vector markup that becomes real DOM elements – perfect for sharp, scalable, and interactive diagrams, icons, and maps.
Choosing between Canvas and SVG depends on what you care about more: raw performance with many drawing operations (Canvas) or crisp scaling and easy interactivity through the DOM and CSS (SVG).
devicePixelRatio-aware rendering.<rect>, <circle>, etc.) is a DOM node.The <canvas> element itself is just a pixel surface. All actual drawing (lines, shapes, images) happens through a JavaScript drawing context:
<!-- Canvas: bitmap drawing surface -->
<canvas id="myCanvas" width="300" height="200">Fallback text</canvas>
<!-- SVG: vector graphics in the DOM -->
<svg viewBox="0 0 300 200" xmlns="http://www.w3.org/2000/svg">
<rect x="50" y="50" width="200" height="100" fill="blue" />
</svg>
Canvas drawing is imperative (step-by-step drawing commands). SVG is declarative (you describe shapes and let the browser render them).
<!-- Canvas: draw a blue rectangle with high-DPI fix -->
<canvas id="c" width="300" height="200">Canvas fallback text</canvas>
<script>
function setupCanvas(canvas, cssW, cssH){
const ratio = Math.max(1, Math.floor(window.devicePixelRatio || 1));
canvas.style.width = cssW + 'px';
canvas.style.height = cssH + 'px';
canvas.width = cssW * ratio;
canvas.height = cssH * ratio;
const ctx = canvas.getContext('2d');
ctx.setTransform(ratio, 0, 0, ratio, 0, 0); // scale drawing ops
return ctx;
}
const ctx = setupCanvas(document.getElementById('c'), 300, 200);
ctx.fillStyle = 'blue';
ctx.fillRect(50, 50, 200, 100);
</script>
<!-- SVG: same rectangle, crisp at any zoom -->
<svg viewBox="0 0 300 200" class="svg-responsive" aria-label="SVG Blue Rectangle"
role="img" xmlns="http://www.w3.org/2000/svg">
<rect x="50" y="50" width="200" height="100" fill="blue" />
</svg>
Below, the Canvas side draws a rectangle and an animated bouncing ball using JavaScript. The SVG side shows a static rectangle that you can interact with as a normal DOM element.
Tip: Click inside the blue shape. In SVG, the rectangle gets the click directly. In Canvas, your code must calculate whether the click was inside the drawn area.
// Canvas: manual hit-test
canvas.addEventListener('click', (e) => {
const r = canvas.getBoundingClientRect();
const x = e.clientX - r.left;
const y = e.clientY - r.top;
if (x >= 50 && x <= 250 && y >= 50 && y <= 150) {
alert('Canvas rect clicked');
}
});
// SVG: attach directly to the shape
document.getElementById('svgRect').addEventListener('click', () => {
alert('SVG rect clicked');
});
devicePixelRatio for HiDPI / retina displays.viewBox and control size with CSS; avoid fixed width/height for flexible layouts.requestAnimationFrame for smooth, synced updates (for both Canvas and SVG).aria-label or <title> to SVG; Canvas usually needs separate text or ARIA descriptions.<circle> to the SVG and change its fill on hover using CSS only.requestAnimationFrame to move it left and right.width/height, keep a viewBox, and set max-width: 100% via CSS.toDataURL() (build your own “Download” button like in the demo).