Skip to content

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.

Published
Reading
1 min
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.

https://www.youtube.com/watch?v=TUtKGTeFWjQ

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.

javascript
<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

More in WebGPU

See all