Google Introduces HTML-in-Canvas API: Accessible UI Meets WebGL / WebGPU

At Google I/O 2026, Chrome engineer Thomas Nattestad unveiled the HTML-in-Canvas API, which is a new web platform feature that lets developers render HTML elements directly into canvas, WebGL, and WebGPU contexts while preserving accessibility and interactivity.

At Google I/O 2026, Chrome engineer Thomas Nattestad unveiled the HTML-in-Canvas API, which is a new web platform feature that lets developers render HTML elements directly into canvas, WebGL, and WebGPU contexts while preserving accessibility and interactivity.

The Problem It Solves

Building UI for 3D web experiences has long forced developers into an uncomfortable choice: overlay HTML elements on top of canvas (breaking immersion and causing z-order headaches), or rebuild UI systems from scratch inside the canvas (losing accessibility, internationalization, and native browser features like text selection and form inputs).

HTML-in-Canvas eliminates this trade-off. A form rendered as a texture on a 3D surface still works with screen readers. Buttons on a spinning cube still respond to clicks. Text inputs on a curved menu still show blinking cursors.

How It Works

The API introduces three core primitives:

  1. layoutsubtree attribute — Opt-in for canvas children to participate in layout and hit testing
  2. drawElementImage() — Draw a child element into the canvas (with WebGL and WebGPU equivalents)
  3. paint event — Fires when canvas children change, enabling efficient updates

For WebGL, there's texElementImage2D(). For WebGPU, there's copyElementImageToTexture(). Both render HTML to textures while keeping the DOM synchronized for accessibility.

<canvas id="canvas" layoutsubtree>
  <form id="myForm">
    <input type="text" placeholder="Type here...">
  </form>
</canvas>

<script>
  const ctx = canvas.getContext('2d');
  canvas.onpaint = () => {
    ctx.reset();
    const transform = ctx.drawElementImage(myForm, 100, 50);
    myForm.style.transform = transform.toString();
  };
</script>

Framework Support

Three.js and PlayCanvas integrations are already available. The Three.js implementation (PR #31233 by mrdoob) adds an HTMLTexture class that handles the synchronization automatically.

Try It Now

The API is available behind a flag in Chrome Canary:


Resources