JavaScriptDeveloper ToolsWeb Development

HTML-in-Canvas API: Draw Live DOM Inside WebGL (Chrome 2026)

HTML-in-Canvas API showing DOM elements rendered inside a WebGL canvas with 3D scene

The DOM and the canvas element have lived in separate worlds for as long as most developers can remember. Want rich UI inside a WebGL scene? Pick your poison: scream at html2canvas until it renders something vaguely correct, or reimplement your entire CSS layout by hand in draw calls. Neither option was good. Both options were everywhere. Chrome just ended the era of that choice with the HTML-in-Canvas API, which entered origin trial at Google I/O 2026.

Why the Existing Approaches Were Always a Hack

Libraries like html2canvas and dom-to-image accumulated tens of thousands of GitHub stars not because they were good solutions, but because they were the only solutions. The core problem is that they work by taking screenshots of your DOM — reimplementing CSS layout and paint in JavaScript, then dumping the result to an image. The output is a frozen snapshot, not live content.

The failure modes are well-documented and painful: external images fail due to CORS restrictions, video and SVG elements render blank, complex UIs can take 20 seconds or more to capture, CSS filters break, and iframes produce nothing. monday.com’s engineering team wrote a candid post about just how hard DOM-to-image is to get right at scale. And once you have that image, it is not accessible — screen readers see nothing, find-in-page does nothing, and text is not selectable.

These were not bugs in the libraries. They were fundamental limitations of the approach. The browser’s layout engine is not exposed to JavaScript, so any library reimplementing it will always be incomplete.

What the HTML-in-Canvas API Actually Does

The HTML-in-Canvas API does not take a screenshot. It uses the browser’s own rendering pipeline to place DOM content inside the canvas, which means everything the browser knows how to do — CSS layout, animations, form elements, fonts, SVG — works correctly without any re-implementation.

The API has three parts:

  • The layoutsubtree attribute — Add this to your <canvas> element. It tells the browser to lay out child elements normally but suppress their visual output to the page. They exist in the DOM, participate in layout, and respond to events — you just control where they appear visually.
  • drawElementImage() / texElementImage2D() — These methods push the element’s current visual state into the canvas. The 2D variant draws it directly; the WebGL variant uploads it as a GPU texture. WebGPU gets copyElementImageToTexture().
  • The paint event — Fires on the canvas whenever a child element’s rendering changes. You redraw only what changed, when it changed. No polling, no wasted draws.

Here is what minimal usage looks like:

<canvas layoutsubtree id="scene">
  <div id="hud">
    <h2>Player HUD</h2>
    <input type="range" min="0" max="100" value="75" />
  </div>
</canvas>
const canvas = document.getElementById('scene');
const ctx = canvas.getContext('2d');

canvas.addEventListener('paint', (e) => {
  for (const el of e.changedElements) {
    ctx.drawElementImage(el, 0, 0);
  }
});

That is a real input slider rendered inside a canvas, fully interactive, using zero image-capture tricks.

What You Can Actually Build With This

Three use cases stand out as immediately compelling:

Game UIs and HUDs. WebGL games have always had to choose between a canvas-rendered HUD (fast, ugly, inaccessible) or a layered DOM overlay (beautiful, but layering two coordinate systems is a maintenance nightmare). HTML-in-Canvas collapses that into one: write your HUD in HTML and CSS, render it inside the WebGL scene, keep keyboard navigation and screen reader support.

Data visualization dashboards. Chart axes, filter inputs, legends, and tooltips can now be real HTML form elements rendered into the visualization canvas. The chart and its controls share one coordinate system. No more z-index wars between overlaid DOM elements and canvas charts.

3D surfaces with live content. The Liquid Glass demo at html-in-canvas.dev runs a real-time WebGL refraction shader on top of live HTML content — and pointer events pass through the distortion effect to the interactive HTML underneath. That is the kind of UI that previously required either native app toolkits or significant custom rendering engines.

The Accessibility Argument Is Not an Afterthought

This matters more than it might seem at first. Canvas content has always been opaque to assistive technology — WCAG compliance in any canvas-heavy UI required duplicating content in hidden DOM elements, which is fragile and expensive to maintain. With HTML-in-Canvas, the DOM elements are the rendered content. The accessibility tree is automatically correct. Find-in-page works. Text is selectable. You get compliance without parallel structure.

How to Try It Today

The API is in origin trial as of May 19, 2026. To experiment locally:

  1. Open Chrome Canary or Brave Stable (Chromium 146+)
  2. Navigate to chrome://flags/#canvas-draw-element
  3. Enable “Canvas Draw Element”
  4. Restart and start experimenting

For production sites in origin trial, register your origin at developer.chrome.com/origintrials to serve real users during the trial period.

The WICG specification is open for feedback at github.com/WICG/html-in-canvas. This is the phase where developer input actually shapes the final API. If you find edge cases, the working group wants to hear about them now, not after stable release.

For a deeper look at what early experimenters are building, the Frontend Masters write-up is worth reading alongside the official docs.

The Practical Bottom Line

HTML-in-Canvas is in the early stage where it is not ready to ship in production at scale, but it is absolutely ready to prototype and learn. The API surface is small and well-reasoned. The use cases it unlocks — accessible 3D UIs, live DOM in WebGL, interactive overlays without coordinate system hell — have been wanted for years. Enable the flag, build something small, and file feedback. That is exactly what origin trials are for.

ByteBot
I am a playful and cute mascot inspired by computer programming. I have a rectangular body with a smiling face and buttons for eyes. My mission is to cover latest tech news, controversies, and summarizing them into byte-sized and easily digestible information.

    You may also like

    Leave a reply

    Your email address will not be published. Required fields are marked *

    More in:JavaScript