Glossary

Canvas

Canvas is the HTML element, written as the canvas tag, that gives JavaScript a bitmap of pixels to draw on through a 2D or WebGL rendering context. It is defined in the WHATWG HTML Living Standard. A new canvas is 300 pixels wide and 150 pixels tall unless you set the width and height attributes.

How it works

A canvas holds a bitmap and nothing else. You call getContext with an identifier such as "2d", "webgl" or "webgl2" and draw with the returned object. Once drawn, shapes are just pixels: the browser keeps no list of objects, so you redraw the whole scene yourself to move something. This is the main difference from SVG and the DOM, where every shape stays addressable.

  • Bitmap size vs CSS size: the width and height attributes set the bitmap resolution. CSS width and height only stretch it. On a display with a device pixel ratio of 2, a canvas shown at 200 by 100 CSS pixels needs a 400 by 200 bitmap to stay sharp.
  • One context per canvas: the first successful getContext call fixes the mode. Asking again for the same mode returns the same object. Asking for a different mode returns null.
  • Reset on resize: for a 2D context, assigning width or height, even to the same value, clears the bitmap and resets the context state.
  • Export: toDataURL returns a PNG data URL by default, and toBlob gives a file-like Blob. A canvas with a zero width or height exports as the string "data:,".
  • Off the main thread: OffscreenCanvas draws without a DOM element and is available in web workers.
const c = document.createElement('canvas');
console.log([c.width, c.height]);

const ctx = c.getContext('2d');
ctx.fillStyle = '#ff0000';
ctx.fillRect(0, 0, 10, 10);
console.log(Array.from(ctx.getImageData(5, 5, 1, 1).data));
console.log(c.getContext('2d') === ctx, c.getContext('webgl'));

c.width = c.width;
console.log(Array.from(ctx.getImageData(5, 5, 1, 1).data));
console.log(c.toDataURL().slice(0, 22));

Run in headless Chromium 141, the console shows these lines. Chromium also logs a willReadFrequently performance hint after the second getImageData call, left out here.

[300, 150]
[255, 0, 0, 255]
true null
[0, 0, 0, 0]
data:image/png;base64,

What is the default size of a canvas?

The default size of a canvas is 300 by 150 pixels. The same defaults apply when an attribute is missing or holds a value that is not a valid non-negative integer. In Chromium, setting the width attribute to "abc" gives a width of 300.

Why does getImageData throw a SecurityError?

It throws because the canvas is tainted: you drew a cross-origin image that the server did not approve with CORS. A tainted canvas blocks reading pixels, so getImageData, toDataURL and toBlob all throw SecurityError. The fix has two parts. Set crossOrigin to "anonymous" on the image, and make the image server send an Access-Control-Allow-Origin header. In a test, an image with the header and crossOrigin set was readable. The same image without crossOrigin still tainted the canvas, and an image without the header failed to load at all when crossOrigin was set.

Common pitfalls

  • Blurry output on high-density screens: the bitmap is scaled up by CSS. Multiply the attribute size by window.devicePixelRatio, keep the CSS size the same, and call scale on the context.
  • Resizing wipes the drawing: setting width or height clears everything, so redraw after any resize.
  • Mixing context types: after getContext("2d") succeeds, getContext("webgl") returns null on the same element. Use a second canvas.
  • Tainted canvas: drawing a cross-origin image without CORS blocks pixel reads and exports with a SecurityError.
  • No accessibility for free: the bitmap exposes nothing to screen readers. Add fallback content inside the canvas element or a text alternative nearby.

Related terms

  • WebGL — the hardware-accelerated 3D context you request from a canvas with getContext
  • DOM — the tree of addressable nodes that a canvas replaces with a single bitmap
  • sRGB — the default color space of 2D canvas drawing
  • Base64 — the encoding inside the data URL that toDataURL returns

See also

  • Term: WebGL — draws 2D and 3D graphics on the same element with the GPU