WICG Specification

Render HTML into Canvas — natively

The HTML-in-Canvas spec adds three primitives that let you draw fully-styled, accessible HTML content straight into <canvas> — no hacks, no libraries, no screenshots.

Three Primitives, One New Superpower

The spec introduces a minimal, composable API surface — each piece solves a distinct problem.

1

layoutsubtree

Add this attribute to a <canvas> to opt its children into layout and hit testing — they behave like normal DOM elements but remain invisible until drawn.

<canvas layoutsubtree>
  <div id="content">
    Laid out, accessible,
    ready to draw.
  </div>
</canvas>
2

drawElementImage()

Draws a child element into the canvas with the current transform applied. Works across 2D, WebGL, and WebGPU contexts.

const t = ctx.drawElementImage(
  element, x, y
);
// Sync DOM position
element.style.transform =
  t.toString();
3

paint event

Fires whenever a child element's rendering changes — clear the canvas and redraw in one efficient callback, once per frame.

canvas.onpaint = (e) => {
  ctx.reset();
  for (const el of e.changedElements) {
    ctx.drawElementImage(el, 0, 0);
  }
};

Why This Matters

Accessibility built in

Drawn elements are the fallback content — the accessibility tree always matches what's on screen.

Real CSS rendering

Fonts, ligatures, RTL, subpixel rendering — the browser does the hard work, not a polyfill.

No hacks required

Replace html2canvas-style workarounds with a native API that's fast, correct, and privacy-preserving.

2D, WebGL & WebGPU

One API surface that works across all three canvas contexts — render HTML as 3D textures, apply shaders, and more.

Featured Demos

View all demos

Get Started

The HTML-in-Canvas API is available today in Chrome Canary behind the canvas-draw-element flag. Enable it, open a demo, and start experimenting.