Chrome is trialling an API that draws real HTML into a canvas. Here is what the proposal withholds from the pixels, and what it leaves readable.
Chrome is experimenting with an API that lets a <canvas> draw real, styled HTML instead of only lines, rectangles and text strings. That raises an obvious privacy question: a canvas can be read back as pixels, and reading canvas pixels is the basis of canvas fingerprinting. If the canvas can now contain a rendered page, what could a script read out of it? The proposal's authors answer with a specific list of things that must never be painted. This article walks through that list and what it tells us. It is an experiment, not a shipped feature.
Key Takeaways
- HTML-in-Canvas is a proposal in a Chrome origin trial, not a shipped web standard. Per Chrome's own post, the trial runs through Chrome 160 and method names have already changed (for example in Chrome 155).
- The core privacy rule is "read-back-allowed rendering": drawing an element must not reveal anything sensitive that page code could not already observe.
- The explainer excludes cross-origin content, system colours and themes, spelling markers, visited-link state, pending autofill and subpixel text anti-aliasing from the painted output.
- It deliberately leaves in things it calls already detectable, such as scrollbar and form-control appearance, caret blink rate and
forced-colors. - Nothing here is a fingerprinting technique that exists today. It is a design that tries to avoid creating a new one.
What the API does
Today a canvas draws primitives. You can paint a string with fillText(), but you cannot hand it a styled <div> with layout, wrapping and form controls. The HTML-in-Canvas proposal, developed in the W3C's WICG repository, adds a way to take a snapshot of an element and draw it into 2D, WebGL or WebGPU canvases, with a method called drawElementImage() for the 2D case. Chrome's post on the origin trial changes notes that the trial is extended through Chrome 160 and that some method and attribute names changed in Chrome 155, so treat any code you see as provisional. The feature also has a Chrome Platform Status entry.
The motivation is mostly creative and practical: effects on real HTML, text in 3D scenes, accessible content inside a canvas. Privacy is a constraint on the design, not the goal.
Why a canvas is a privacy-sensitive surface
A canvas is not just an output. Script can call toDataURL() or getImageData() and get every pixel back as data. That is exactly how canvas fingerprinting works: draw a fixed scene, read it back, hash it. The hash varies because GPUs, drivers, font rasterisers and operating systems differ. See our browser fingerprinting guide for the wider picture.
Now imagine a canvas that can contain a rendered page. The browser paints things a page script never sees directly: whether a link is visited, what colour the operating system theme is, whether the spell-checker underlined a word. If those leaked into the painted pixels, a script could read them back out, and a harmless-looking drawing call would become a window into private state.
The "read-back-allowed" rule
The explainer handles this with one principle, which it calls read-back-allowed rendering. In its words, drawing an element and the related paint event "must not reveal any security- or privacy-sensitive information that isn't otherwise observable to author code". Because pixel readback is always possible with WebGL and WebGPU, the safe approach is to keep sensitive information out of the painted output in the first place. The text frames this as preventing leaks through pixel readbacks, timing attacks and invalidation events. It does not mention fingerprinting by name; this is a security and privacy rule, and the fingerprinting reading below is ours.
What gets left out of the pixels
The explainer lists what must be excluded from painting:
- Cross-origin data in embedded content such as iframes and images, URL references like
background-image, canvases tainted by cross-origin data, and SVG references. Same-origin iframes still paint; cross-origin content inside them does not. - System colours, themes or preferences.
- Spelling and grammar markers.
- Visited-link information.
- Pending form autofill information that JavaScript cannot otherwise see.
- Subpixel text anti-aliasing.
- Captions and video controls.
- IME pop-ups and distinctive IME text formatting.
Most of these are obvious leak candidates (visited links and autofill are classic history-sniffing targets). The subpixel anti-aliasing item is the interesting one for fingerprinting. How a platform smooths text edges depends on the operating system, display and settings, and it is part of why the same text looks slightly different on different machines. Ordinary fillText() on a canvas already exposes much of that rendering behaviour, which is a core ingredient of font and text-rendering fingerprinting. Excluding it from the new path means the new API does not add a fresh, higher-resolution way to read it.
That contrast matters. The proposal does not fix existing canvas fingerprinting; it declines to make the surface bigger.
What is deliberately left in
The explainer also lists information it does not consider sensitive in this context:
- find-in-page text and text-fragment markers,
- scrollbar and form-element appearance, which it says is already detectable in Blink and WebKit through
foreignObject, - caret blink rate,
forced-colors, which it notes is already available to JavaScript through the media query and system colours.
The reasoning is consistent: if page code can already observe a value, painting it adds no new information. That is a defensible rule, but it also shows the limit. Signals such as forced-colors are already part of what CSS media-query fingerprinting collects, so they remain available to trackers either way. The proposal does not claim to reduce them.
The GPU paths
The same readback problem exists on the GPU side, and the explainer says pixel readback is always possible with WebGL and WebGPU. That is why the exclusion rules apply to the variants that draw element snapshots into those contexts too: currently texElementSubImage2D() for WebGL and drawElementImageToTexture() for WebGPU, both names that changed in Chrome 155. For background on what those contexts already reveal, see our WebGL fingerprinting deep dive and WebGPU fingerprinting.
Honest limits
- It is a proposal and an experiment. Chrome's trial can change or end, and privacy review could alter the exclusion list.
- We found no commitments from other engines on the pages we cite, so we make no claims about Firefox or Safari.
- A rule written in a design document is only as good as its implementation. Edge cases (timing, invalidation, unusual element types) are exactly where such rules tend to leak, which is why the explainer names timing attacks explicitly.
- Nothing here changes what canvas fingerprinting can do today.
What this means for you
For visitors: nothing changes now. An origin trial only runs on sites that have registered for it, and only in Chrome versions inside the trial window; you do not opt in yourself. If you want to reduce canvas fingerprinting regardless, read how canvas noise and randomisation can backfire, and favour uniformity over randomness.
For developers: if you experiment with the API, assume provisional names, and do not rely on being able to capture sensitive state in a canvas. That is by design.
Check your own canvas hash
BrowserInsight's fingerprint check computes a canvas hash with the standard 2D canvas API. It does not use HTML-in-Canvas. It is a good way to see what a script reading an ordinary canvas can already get from your browser today.


