9 November 2026 · Web geliştirme
HTML-in-Canvas ships in Chrome 157: UI inside a canvas can now be real DOM
Chrome 157 ships the HTML-in-Canvas API, which lets you draw real HTML elements into a canvas while keeping them accessible, selectable and translatable. Firefox isn't convinced yet. Here's what the API solves and how to use it responsibly today.
Anyone who has worked with canvas knows the catch: to the browser, everything you draw is just pixels. Screen readers can't read the text, find-in-page can't locate it, automatic translation ignores it and users can't select or copy it. So for games, data visualizations and 3D scenes we usually stack absolutely positioned HTML over the canvas, or we rebuild text layout, line breaking and even input fields inside the canvas ourselves.
Chrome 157, which reached the stable channel on November 3, changes this. The HTML-in-Canvas API is no longer behind a flag. You can draw real DOM elements into 2D, WebGL and WebGPU canvases, and because those elements stay in the DOM, accessibility, find-in-page, translation and DevTools keep working.
How the API works
The model is fairly simple. Children of a canvas are no longer just fallback content. When you set content="drawable" on the canvas, the browser lays out that subtree, and you mark each element you want to render with the drawable attribute. Drawing happens in the paint event:
<canvas id="c" content="drawable" style="width:400px;height:200px">
<form id="panel" drawable>
<label>Email <input type="email"></label>
<button type="submit">Send</button>
</form>
</canvas>
<script>
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
const panel = document.getElementById('panel');
canvas.onpaint = () => {
ctx.reset();
ctx.drawElementImage(panel, 0, 0);
};
</script>That form is a real form: you can type into the input and click the button. In a 2D context, drawElementImage() automatically lines up the hit-test area and the screen reader focus ring with wherever you drew the element.
In 3D you do more of the work yourself:
- WebGL:
texElementSubImage2D()copies the element into a pre-allocated texture. - WebGPU:
device.queue.drawElementImageToTexture()does the same. - In both cases the browser can't know where the element ends up in your scene, so you pass a transform via
canvas.updateElementGeometry()for hit testing and accessibility. Skip it and the element stays in the accessibility tree but has no on-screen position.
There's also a performance hook: the changedElements list on the paint event tells you which elements actually changed, so you can redraw only what's needed instead of everything every frame.
Why it matters
To me, the real win is that the wall between two worlds gets thinner. Until now we had to choose between canvas effects and an accessible, translatable UI. In practice:
- Game and 3D UIs: Menus, inventories or chat panels can be written in HTML and CSS and turned into textures. No custom engine for text layout, RTL scripts, emoji or font fallback.
- Data visualization: Labels and annotations remain real text that screen readers and find-in-page can reach.
- Editors and design tools: Canvas-based editors have less reason to reinvent text fields.
- Screenshots and export: Instead of libraries like html2canvas that re-implement rendering in JavaScript, you can lean on the browser's own output.
The API also changed several times while maturing. Chrome 150 and 155 renamed methods and reshaped their signatures, and the old boolean layoutsubtree attribute became content="drawable". If you wrote code during the origin trial, check those renames first.
The other side: Firefox isn't on board
Before rolling this out everywhere, look at the standards picture. Today it exists only in Chromium-based browsers; Safari and Firefox have no implementation.
The discussion in Mozilla's standards-positions repo is worth reading. Mozilla hasn't published a formal position yet, but its concerns are substantial:
- Privacy and fingerprinting: Letting scripts read back rendered DOM pixels could leak browser-specific rendering such as form controls or scrollbars. Chrome points to a readback mode that excludes cross-origin content; Mozilla argues such an exclusion list will have a long tail that never ends.
- Platform direction: Mozilla doesn't think the web should encourage building rich UIs on canvas, and worries it undermines key rendering pipeline optimizations.
- Compatibility pressure: An API that spreads through a single engine can become a de facto standard other browsers feel forced to follow.
Chrome's own guide also draws a clear line: embedding cross-origin content inside the canvas isn't supported. So don't expect to render iframe ads or third-party widgets this way.
What to do in practice
If you want to use it in production today, progressive enhancement is the only sensible route:
if ('content' in HTMLCanvasElement.prototype) {
// HTML-in-Canvas path
} else {
// position the HTML over the canvas with CSS
}A few recommendations:
- Design the fallback as a first-class path. Safari and Firefox users aren't an edge case. Keep the classic HTML-over-canvas approach working.
- Don't assume accessibility comes for free. In 2D most things line up automatically, but forget
updateElementGeometry()in WebGL/WebGPU and screen reader users get a broken experience. - Start with internal tools. Dashboards, Electron apps or kiosk screens where you control the browser are good testing grounds.
- Watch the standards process. The API is headed to WHATWG and details may still change.
Final thoughts
HTML-in-Canvas tackles a long-standing tension on the web: offering visual freedom and accessibility at the same time. With Chrome 157 you can try it without flags. But being stable in one browser isn't the same as being a stable part of the web. My advice: design your next game UI, charting library or canvas-based editor so it can take advantage of this API, but make sure it works without it. What Firefox and Safari decide will determine whether this stays a Chrome feature or becomes a shared tool of the web.
Sources
- Expose canvas content to browser features – Chrome for Developers
- HTML-in-Canvas updates: Iterating toward a better Web API – Chrome for Developers
- Chrome 157 HTML-in-Canvas API – mdn/browser-compat-data PR #30938
- Chrome 157 Is Out: 213 Security Fixes and What Is New – Chrome Geek
- Mozilla standards-positions: HTML-in-canvas (issue #1076)
- WICG html-in-canvas explainer
- This Week In React #304