HTMLCanvas Basics (<canvas>)

Canvas Basics

<canvas> is a blank rectangular drawing surface. By itself, an empty <canvas> renders as nothing more than an invisible box—every pixel on it has to be drawn with JavaScript. That's the fundamental trade-off to understand before anything else: canvas is a pixel-based drawing API, not a markup language for graphics.
Declaring a Canvas

canvas-element.html

HTML
<canvas id="scene" width="400" height="300">
  Your browser doesn't support the canvas element.
</canvas>
Set width/height as HTML attributes (not CSS) to define the canvas's actual pixel grid—sizing it only with CSS stretches or squashes the drawing instead of giving you more pixels to draw on. The text inside the tag is fallback content for browsers that don't support canvas at all.
Getting a 2D Rendering Context
A <canvas> element does nothing until you grab a rendering context—an object with the drawing methods you'll actually call. The most common is the 2D context.

canvas-2d.html

HTML
<canvas id="scene" width="400" height="300"></canvas>

<script>
  const canvas = document.getElementById('scene');
  const ctx = canvas.getContext('2d');

  // Draw a filled rectangle
  ctx.fillStyle = '#3b82f6';
  ctx.fillRect(20, 20, 120, 80);

  // Draw a circle (canvas has no built-in "circle" — you draw an arc)
  ctx.beginPath();
  ctx.arc(250, 60, 40, 0, Math.PI * 2);
  ctx.fillStyle = '#ef4444';
  ctx.fill();

  // Draw text
  ctx.font = '16px sans-serif';
  ctx.fillStyle = '#111827';
  ctx.fillText('Hello, canvas!', 20, 150);
</script>

Every shape is drawn imperatively, one method call at a time. Canvas has no memory of "the rectangle I drew a moment ago"—once pixels are painted, they're just pixels. To change or animate a shape, you redraw the whole scene (or the affected region) from scratch.

Canvas vs SVG

SVG (covered in the next lesson) also draws graphics in the browser, but the two work in opposite ways: SVG keeps every shape as an element in the DOM, while canvas only remembers pixels.

Consideration

Canvas

SVG

Representation

Flat pixel bitmap, no memory of individual shapes

Live DOM elements—each shape is inspectable and stylable

Scaling

Blurs when scaled up (raster)

Stays crisp at any size (vector)

Best for

Games, complex animations, image/video processing, thousands of moving objects

Icons, diagrams, charts, illustrations, anything needing individual element interactivity

Accessibility

Content is invisible to screen readers unless you duplicate it as fallback/ARIA

Elements can carry titles/descriptions and are more inspectable by assistive tech

Editing after drawing

Requires redrawing (no per-shape references)

Just update the element/attribute (e.g. via CSS or the DOM)

Rule of thumb: many simple, changing objects → canvas; fewer, distinct, interactive shapes → SVG
A particle system with thousands of moving dots is a canvas problem. A dashboard with a dozen clickable, labeled bars is usually better as SVG (or a charting library built on it).
Canvas draws nothing without JavaScript
Unlike an <img> or inline <svg>, a <canvas> with no script attached is just an empty box. If JavaScript fails to load or is disabled, users see only the fallback content (or nothing).
A Minimal Animation Loop

canvas-animation.html

HTML
<canvas id="scene" width="400" height="150"></canvas>

<script>
  const ctx = document.getElementById('scene').getContext('2d');
  let x = 0;

  function frame() {
    ctx.clearRect(0, 0, 400, 150); // erase the previous frame
    ctx.fillStyle = '#22c55e';
    ctx.fillRect(x, 60, 30, 30);
    x = (x + 2) % 400;
    requestAnimationFrame(frame);
  }

  frame();
</script>
Animation on canvas means clearing and redrawing the whole scene on every frame (usually via requestAnimationFrame)—there's no concept of moving "the rectangle" independently, because canvas never kept a reference to it in the first place.
Accessible alternatives matter here
Because canvas content is invisible to screen readers by default, provide meaningful fallback content, an accessible text summary, or an ARIA live region for any information conveyed only through the drawing.
Sizing Pitfalls: Attributes vs CSS
A very common beginner mistake is sizing a canvas only with CSS. The canvas's internal pixel grid stays whatever the width/height attributes say (300×150 by default if omitted), while CSS just stretches that grid to a different display size—causing blurry, distorted drawings.

sizing-pitfall.html

HTML
<!-- Wrong: canvas still draws at 300x150 internally, then gets stretched -->
<canvas id="bad" style="width: 800px; height: 400px;"></canvas>

<!-- Right: internal pixel grid matches the intended display size -->
<canvas id="good" width="800" height="400"></canvas>
A Simple Interactive Example

Canvas content can respond to user input too—mouse coordinates are read relative to the canvas element, then used in drawing calls.

canvas-drawing.html

HTML
<canvas id="pad" width="400" height="200" style="border: 1px solid #ccc;"></canvas>

<script>
  const canvas = document.getElementById('pad');
  const ctx = canvas.getContext('2d');
  let drawing = false;

  canvas.addEventListener('mousedown', () => { drawing = true; });
  canvas.addEventListener('mouseup', () => { drawing = false; });
  canvas.addEventListener('mousemove', (event) => {
    if (!drawing) return;
    const rect = canvas.getBoundingClientRect();
    ctx.fillRect(event.clientX - rect.left, event.clientY - rect.top, 3, 3);
  });
</script>
Common Use Cases

Use case

Why canvas fits

2D games

Frequent full-scene redraws at 60fps; no DOM overhead per object

Data visualization with huge datasets

Thousands of points render faster as pixels than as DOM nodes

Image editing / filters

Direct pixel manipulation via getImageData/putImageData

Drawing/whiteboard apps

Freeform strokes map naturally to pixel painting

Generated thumbnails/QR codes

Programmatic pixel output, often exported via toDataURL()

  • <canvas> is a blank drawing surface—set width/height as attributes, not CSS.

  • Get a rendering context (2D, or WebGL for 3D) before you can draw anything.

  • Canvas remembers only pixels, not shapes—redrawing is how you update or animate content.

  • Choose canvas for many changing pixels (games, particle effects); choose SVG for distinct, inspectable, interactive shapes.

  • Canvas draws nothing without JavaScript—always provide meaningful fallback content.