Learn how to use the HTML Canvas element to draw shapes, text, and graphics programmatically using JavaScript and the 2D rendering context.
The <canvas> element provides a bitmap drawing surface that you control entirely with JavaScript. Unlike SVG (which uses DOM elements for each shape), Canvas gives you a blank pixel grid and a drawing API.
Canvas is ideal for:
The trade-off: Canvas content is not part of the DOM, so it is not directly accessible to screen readers or searchable. You must provide fallback content and ARIA attributes.
The <canvas> element has two important dimension systems:
width and height — Define the drawing surface resolution (in pixels). Default: 300x150.If these do not match, the image will be stretched or squished. For crisp rendering, set the HTML attributes to match the desired resolution.
<canvas id="myCanvas" width="400" height="300">
Your browser does not support the canvas element.
</canvas>The text between the tags is fallback content displayed if the browser does not support Canvas.
To draw, you get the 2D rendering context in JavaScript:
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');The 2D context provides methods for drawing:
ctx.fillRect(x, y, width, height) — Filled rectangle.ctx.strokeRect(x, y, width, height) — Outlined rectangle.ctx.clearRect(x, y, width, height) — Erases a rectangular area.ctx.beginPath();
ctx.arc(100, 100, 50, 0, Math.PI * 2); // circle
ctx.fill();ctx.beginPath() — Starts a new path.ctx.moveTo(x, y) — Moves the pen without drawing.ctx.lineTo(x, y) — Draws a line to (x, y).ctx.arc(x, y, radius, startAngle, endAngle) — Draws an arc or circle.ctx.fill() — Fills the current path.ctx.stroke() — Outlines the current path.ctx.font = '20px Arial' — Sets the font.ctx.fillText('Hello', x, y) — Draws filled text.ctx.strokeText('Hello', x, y) — Draws outlined text.ctx.fillStyle = '#e74c3c' — Sets fill colour.ctx.strokeStyle = '#2ecc71' — Sets stroke colour.<canvas id="demo" width="300" height="200">
Fallback: your browser does not support canvas.
</canvas>
<script>
const canvas = document.getElementById('demo');
const ctx = canvas.getContext('2d');
// Blue rectangle
ctx.fillStyle = '#3498db';
ctx.fillRect(20, 20, 100, 80);
// Red circle
ctx.fillStyle = '#e74c3c';
ctx.beginPath();
ctx.arc(200, 60, 40, 0, Math.PI * 2);
ctx.fill();
// Text
ctx.fillStyle = '#ecf0f1';
ctx.font = '18px sans-serif';
ctx.fillText('Canvas!', 100, 160);
</script>Canvas content is invisible to assistive technologies by default. To make it accessible:
role="img" — Tells screen readers the canvas represents an image.aria-label — Provides a text description.<canvas role="img" aria-label="Bar chart showing monthly sales data"
width="400" height="300">
<p>Bar chart: Jan $100, Feb $150, Mar $200</p>
</canvas>For interactive canvas applications (games, tools), consider providing an alternative HTML interface or using ARIA live regions to announce state changes.
Why should you set width and height as HTML attributes on <canvas> rather than using CSS alone?