HTML in Canvas API
An emerging web standard that bridges the DOM and Canvas graphics — allowing live, accessible HTML elements to be painted directly into 2D Canvas, WebGL, and WebGPU.
The Problem: Why Can't We Draw HTML on Canvas?
HTML and Canvas are great at two completely different things:
- HTML & CSS handle text formatting, buttons, forms, scrolling, keyboard navigation, and screen reader accessibility effortlessly.
- HTML5
<canvas>handles high-speed 2D rendering, 3D scenes (WebGL/WebGPU), video processing, and games.
When developers need to combine both — such as putting an interactive computer screen inside a 3D game or adding a styled menu to a canvas app — they historically faced two messy workarounds:
Floating HTML elements on top of the canvas using position: absolute. This breaks whenever the element needs to be rotated, distorted, or placed inside a 3D world.
Writing thousands of lines of custom JavaScript to manually draw text, fake input carets, calculate line wraps, and simulate buttons from scratch inside the canvas.
The Solution: Native HTML-in-Canvas
The HTML in Canvas API is an emerging web platform standard incubated by the WICG (Web Incubator Community Group). It provides a native bridge between real DOM elements and graphics contexts.
Instead of hacking overlays or reinventing text layout, you place regular HTML elements inside the <canvas> tag. The browser’s native rendering engine automatically lays out the HTML and passes it directly to your canvas as a GPU texture.
Why this is a game changer: Because the elements remain real DOM nodes, they stay 100% accessible to screen readers, respond to CSS styles, and support keyboard focus and tab navigation out of the box.
How It Works: The Core Primitives
The proposed API introduces a few simple primitives to connect HTML with Canvas:
1. The layoutsubtree Attribute
Adding layoutsubtree to a <canvas> tells the browser that its child elements should participate in layout and hit testing, but should not be painted in the regular page flow.
2. The paint Event & requestPaint()
Instead of running a heavy animation loop continuously, the canvas fires a paint event only when child HTML visually changes (e.g. on hover, typing, or DOM mutations). You can also request a re-render manually using canvas.requestPaint().
3. Drawing into Graphics Contexts
The specification provides methods tailored for each graphics pipeline:
- 2D Canvas:
ctx.drawElementImage(element, x, y)draws the element and returns a transform matrix to keep click hit-testing aligned. - WebGL:
gl.texElementImage2D(...)uploads the element directly as a 3D texture. - WebGPU:
copyElementImageToTexture()copies the element layout bitmap into a GPU texture.
4. captureElementImage() for Web Workers
For multi-threaded apps using OffscreenCanvas, you can capture an ElementImage snapshot on the main thread and transfer it to a Web Worker for background rendering.
Code Example (Proposed Syntax)
Here is how drawing an interactive HTML card onto a 2D canvas looks with the proposed syntax:
Privacy-Preserving Painting
Because canvas pixel data can be read back using JavaScript (e.g. getImageData()), the specification incorporates strict privacy-preserving painting rules to prevent data leaks:
- Cross-Origin Isolation: Iframes, images, and external stylesheets from other domains are blocked from painting to prevent cross-site data theft.
- User Secrets: Form autofill suggestions, password contents, and spellcheck squiggles are excluded from the paint buffer.
- Browsing History Protection: Visited link styling (
:visited) is treated as unvisited to prevent scripts from probing user history. - Anti-Aliasing Hardening: Subpixel text anti-aliasing is disabled to eliminate pixel-timing attacks.
Current Status & How to Test
The HTML in Canvas API is an active WICG incubation proposal. It is currently available for experimentation behind a feature flag in Chromium browsers (such as Chrome Canary).
Navigate to chrome://flags/#canvas-draw-element, set the flag to Enabled, and restart your browser.
For official technical specifications, discussions, and updates, visit the WICG html-in-canvas GitHub repository and the ChromeStatus entry.
Explore related HTML guides: