HTML-in-Canvas:引爆前端交互!這個提案太瘋狂了!

作者:前端自習課
日期:2026年4月29日 上午7:30
來源:WeChat 原文

整理版優先睇

速讀 5 個重點 高亮

HTML-in-Canvas 提案讓開發者直接用 HTML+CSSCanvas UI,複用瀏覽器排版引擎,解決 DOM 同 Canvas 割裂問題。

整理版摘要

呢篇文章由一個前端開發者角度出發,指出 Canvas 雖然功能強大,但用嚟寫 UI 好原始:畫個掣要手動路徑、排版文本要自計座標、做動畫要自己維護狀態,等於用代碼重寫渲染引擎。作者帶出一個新提案 HTML-in-Canvas,由 WICG 提出,目標係畀瀏覽器將真實 DOM 渲染結果直接繪製到 Canvas 上。

提案核心係引入 layoutsubtree 屬性同 drawElementImage API,令 Canvas 內嘅 DOM 參與佈局但唔直接顯示,由開發者控制幾時繪製。呢個唔係截圖或 SVG hack,而係瀏覽器原生排版結果,文本、樣式、交互都保留。

整體結論係呢個提案雖然仲係實驗階段,但提供咗一種新可能:用 HTML 寫界面、Canvas 驅動渲染,特別適合遊戲 UI、數據可視化、WebGL 場景。

  • HTML-in-Canvas 令開發者用標準 HTML+CSSCanvas UI,唔使手動計算排版。
  • 核心 API 係 drawElementImage,將 DOM 渲染結果繪製到 Canvas
  • 提案保留 DOM 嘅可訪問性,解決傳統 Canvas 對屏幕閲讀器唔友好嘅問題。
  • 文本排版直接複用瀏覽器引擎,解決 Canvas 文本渲染困難。
  • 可以將 HTML 當作紋理用喺 WebGL/WebGPU,實現 3D 場景 UI。
值得記低
連結 wicg.github.io

HTML-in-Canvas 提案說明

WICG 提案,解釋核心概念與動機

連結 github.com

HTML-in-Canvas GitHub 倉庫

包含範例代碼與實驗

整理重點

Canvas 嘅痛點:強大但原始

作為前端,Canvas 唔陌生,但用佢做 UI 好快會發現:寫個按鈕要手畫路徑,排版文本要自己計座標,做動畫要自己維護狀態——本質係用代碼重寫渲染引擎。

DOMCanvas 一直係兩個割裂嘅世界

呢個割裂令開發者好頭痕:要靚排版就用 DOM,要高效渲染就用 Canvas,兩者好難結合。

整理重點

HTML-in-Canvas:原生渲染 DOM 到 Canvas

最近 WICG 提出一個新提案,名好直白:HTML-in-Canvas——喺 <canvas> 裏面用 HTML。你寫嘅係熟悉嘅 HTML+CSS,但最終由 Canvas 負責繪製。

  1. 1 layoutsubtree:令 Canvas 內嘅 DOM 參與佈局,但唔直接顯示,等於一個「可佈局但唔可見」嘅子樹。
  2. 2 drawElementImage:ctx.drawElementImage(element, x, y) 將 DOM 渲染結果繪製到 Canvas,係核心 API
  3. 3 paint 機制:canvas.onpaint 同 canvas.requestPaint(),當 DOM 變化時觸發重繪,接近聲明式更新。
整理重點

解決咗咩問題?

UI 唔再需要「手畫

過去 Canvas 寫 UI 係逐像素繪製,而家可以直接寫 <div class="card">,佈局、換行、樣式全部交畀瀏覽器。

  • 文本排版能力直接複用Canvas 一直唔擅長文本,而家瀏覽器引擎「白送」。
  • 可訪問性回歸DOM 依然存在,屏幕閲讀器可以讀取,對複雜 UI 好重要。
  • 可以進入 GPU 渲染鏈路HTML 當作紋理用喺 WebGLWebGPU、XR 場景。
  • 渲染控制更靈活DOM 負責佈局,Canvas 負責繪製,開發者決定重繪時機。

呢個提案主要解決 Canvas 缺乏高質量文本、UI 構建成本高、a11y 缺失同 GPU 協作唔順暢嘅問題

整理重點

點樣用?實驗特性與 API

目前仲係實驗特性,Chromium 嘅 flag 叫 chrome://flags/#canvas-draw-element。官方 explainer 提供咗示例代碼:

基本用法示例 html
<canvas layoutsubtree>
 <div id="ui">
 <button>點擊我</button>
 </div>
</canvas>

<script>
 const ctx = canvas.getContext("2d");
 ctx.drawElementImage(document.getElementById("ui"), 0, 0);
</script>

drawElementImage 係成個提案最核心嘅 API

官方仲提供咗同 GPU 直接對接嘅能力,例如 WebGL 嘅 texElementImage2D 同 WebGPU 嘅 copyElementImageToTexture。

整理重點

已有案例同未來潛力

已經有大佬做咗好多優秀案例:遊戲 UI、數據可視化、海報生成、WebGL 3D UI

官方案例源碼放咗喺 GitHub,可以參考點樣用 HTML 寫界面、Canvas 驅動渲染。呢個方向如果成熟,對可視化、遊戲同 WebGL 開發者會好有用。

作為一個前端,應該對 Canvas 都唔陌生。

但只要你真係用佢做過 UI,就好快會發現一件事:

Canvas 好強,但都好「原始」。

畫一個掣要手寫路徑,排版文字要自己算座標,做動畫要維護狀態——本質上,你係喺度「用代碼重新寫一層渲染引擎”。

轉折:HTML-in-Canvas

最近,一個新嘅提案開始俾人頻繁討論:HTML-in-Canvas

先睇下個效果:

個名其實好直接——喺 <canvas> 裡面用 HTML。

你寫嘅依然係熟悉嘅 HTML + CSS,但最終由 Canvas 負責繪製。

聽落有啲反直覺,但佢確實係嘗試解決一個老問題:

DOM 和 Canvas,一直係兩個分隔嘅世界。

咩係 HTML-in-Canvas?

HTML-in-Canvas 是 WICG 提出嘅一個新提案,核心目標好明確:

令瀏覽器將真實嘅 DOM 渲染結果,直接繪製到 Canvas 上。

官方相關地址https://wicg.github.io/html-in-canvas/

圖片

官方在 explainer 入面俾出嘅定位係:

在 2D / 3Dcanvas 中渲染 HTML 內容,並保持佢嘅佈局、樣式同交互能力。

留意,呢度有幾個關鍵點:

  • 唔係截圖(html2canvas)
  • 唔係 SVG hack
  • 唔係 foreignObject
  • 而係瀏覽器原生排版結果

同時,呢個提案引入咗一個重要機制:

👉 Canvas 子樹參與佈局,但唔直接顯示,由開發者控制幾時繪製

一個簡單例子:

<canvas layoutsubtree>
  <div id="ui">
    <button>點擊我</button>
  </div>
</canvas>
const ctx = canvas.getContext("2d");
ctx.drawElementImage(document.getElementById("ui"), 00);

你寫嘅係普通 DOM,但最終顯示喺 Canvas 中。

佢解決咗啲咩問題?

由官方動機嚟睇,呢個提案主要係解決 Canvas 長期存在嘅幾個核心問題:

  • 缺乏高質量文字同排版能力
  • UI 構建成本過高
  • 可訪問性(a11y)缺失
  • 同現代渲染管線(GPU)協作唔順暢

UI 唔再需要「手畫」

過去在 Canvas 中寫 UI,本質係逐像素繪製。

而家可以直接寫 HTML

<div class="card">
  <h1>標題</h1>
  <p>內容</p>
</div>

佈局換行樣式全部交俾瀏覽器處理。

文字同排版能力直接重用

Canvas 一路都唔擅長文字:字體換行多語言都比較麻煩。

HTML-in-Canvas 直接重用瀏覽器排版引擎,呢塊基本上係「免費」。

3. 可訪問性回歸

傳統 Canvas 對螢幕閲讀器幾乎睇唔到。

HTML-in-Canvas 中,DOM 依然存在,可以參與語義同交互,呢個對複雜 UI 非常重要。

4. 可以進入 GPU 渲染鏈路

HTML 可以被當做紋理使用:

  • WebGL
  • WebGPU
  • XR 場景

這讓 UI 和 3D 渲染之間嘅邊界變得更加模糊。

5. 渲染控制更加靈活

  • DOM 負責佈局
  • Canvas 負責繪製

你可以自己決定何時重繪如何動畫如何處理像素

點樣用?

目前仲係實驗特性(Chromium 可用):

chrome://flags/#canvas-draw-element
圖片

根據官方 explainer,核心能力主要集中喺幾個點:

layoutsubtree

讓 canvas 內的 DOM 參與佈局,但唔直接顯示。可以理解為「可佈局但不可見嘅子樹」。

drawElementImage

ctx.drawElementImage(element, x, y);

把 DOM 渲染結果繪製到 Canvas

呢個係成個提案最核心嘅 API

paint 機制

canvas.onpaint = () => {};
canvas.requestPaint();

當 DOM 內容變化時觸發重繪。

同傳統相比 Canvas 嘅手動刷新,呢度更加接近「聲明式更新”。

同 GPU 管線結合

官方仲提供咗同 GPU 嘅直接對接能力:

  • WebGLtexElementImage2D
  • WebGPUcopyElementImageToTexture

HTML 可以直接作為紋理參與渲染。

一啲已經出現嘅用法

雖然目前仲喺實驗階段,但已經有大佬做咗非常多嘅優秀案例:

  • 遊戲 UI(HTML 寫界面 + Canvas 渲染)
  • 數據可視化(圖表 + HTML 標籤)
  • 海報生成(直接導出)
  • WebGL / 3D UI(HTML 作為紋理)
  • 設計工具(富文本 + 實時渲染)

一大波案例展示:

官方案例源碼https://github.com/WICG/html-in-canvas/tree/main/Examples

寫喺最後

HTML-in-Canvas 唔一定會即刻改變日常開發,但佢提供咗一種新嘅可能:

用 HTML 寫界面,用 Canvas 驅動渲染。

如果你喺度做可視化遊戲或 WebGL,呢個方向值得多啲留意。

有興趣嘅話,可以開個 flag 試下,感受下呢種「有啲唔同」嘅前端渲染方式。

  • 提案說明https://wicg.github.io/html-in-canvas/
  • Github 地址https://github.com/WICG/html-in-canvas/

作為一名前端,應該對 Canvas 都不陌生。

但只要你真正用它做過 UI,就會很快意識到一件事:

Canvas 很強,但也很“原始”。

畫一個按鈕要手寫路徑,排版文本要自己算座標,做動畫要維護狀態——本質上,你是在“用代碼重寫一層渲染引擎”。

轉折:HTML-in-Canvas

最近,一個新的提案開始被頻繁討論:HTML-in-Canvas

先上個效果:

名字其實很直白——在 <canvas> 裏使用 HTML。

你寫的依然是熟悉的 HTML + CSS,但最終由 Canvas 負責繪製。

這聽起來有點反直覺,但它確實在嘗試解決一個老問題:

DOM 和 Canvas,一直是兩個割裂的世界。

什麼是 HTML-in-Canvas?

HTML-in-Canvas 是 WICG 提出的一個新提案,核心目標很明確:

讓瀏覽器把真實的 DOM 渲染結果,直接繪製到 Canvas 上。

官方相關地址https://wicg.github.io/html-in-canvas/

圖片

官方在 explainer 中給出的定位是:

在 2D / 3Dcanvas 中渲染 HTML 內容,並保持其佈局、樣式和交互能力。

注意,這裏有幾個關鍵點:

  • 不是截圖(html2canvas)
  • 不是 SVG hack
  • 不是 foreignObject
  • 而是瀏覽器原生排版結果

同時,這個提案引入了一個重要機制:

👉 Canvas 子樹參與佈局,但不直接顯示,由開發者控制何時繪製

一個簡單示例:

<canvas layoutsubtree>
  <div id="ui">
    <button>點擊我</button>
  </div>
</canvas>
const ctx = canvas.getContext("2d");
ctx.drawElementImage(document.getElementById("ui"), 00);

你寫的是普通 DOM,但最終顯示在 Canvas 中。

它解決了什麼問題?

從官方動機來看,這個提案主要是在解決 Canvas 長期存在的幾個核心問題:

  • 缺乏高質量文本與排版能力
  • UI 構建成本過高
  • 可訪問性(a11y)缺失
  • 與現代渲染管線(GPU)協作不順暢

UI 不再需要“手畫”

過去在 Canvas 中寫 UI,本質是逐像素繪製。

現在可以直接寫 HTML

<div class="card">
  <h1>標題</h1>
  <p>內容</p>
</div>

佈局換行樣式全部交給瀏覽器處理。

文本和排版能力直接複用

Canvas 一直不擅長文本:字體換行多語言都比較麻煩。

HTML-in-Canvas 直接複用瀏覽器排版引擎,這一塊基本“白送”。

3. 可訪問性迴歸

傳統 Canvas 對屏幕閲讀器幾乎不可見。

HTML-in-Canvas 中,DOM 依然存在,可以參與語義和交互,這對複雜 UI 非常重要。

4. 可以進入 GPU 渲染鏈路

HTML 可以被當作紋理使用:

  • WebGL
  • WebGPU
  • XR 場景

這讓 UI 和 3D 渲染之間的邊界變得更模糊。

5. 渲染控制更靈活

  • DOM 負責佈局
  • Canvas 負責繪製

你可以自己決定何時重繪如何動畫如何處理像素

如何使用?

目前還是實驗特性(Chromium 可用):

chrome://flags/#canvas-draw-element
圖片

根據官方 explainer,核心能力主要集中在幾個點:

layoutsubtree

讓 canvas 內的 DOM 參與佈局,但不直接顯示。可以理解為“可佈局但不可見的子樹”。

drawElementImage

ctx.drawElementImage(element, x, y);

把 DOM 渲染結果繪製到 Canvas

這是整個提案最核心的 API

paint 機制

canvas.onpaint = () => {};
canvas.requestPaint();

當 DOM 內容變化時觸發重繪。

相比傳統 Canvas 的手動刷新,這裏更接近“聲明式更新”。

與 GPU 管線結合

官方還提供了與 GPU 的直接對接能力:

  • WebGLtexElementImage2D
  • WebGPUcopyElementImageToTexture

HTML 可以直接作為紋理參與渲染。

一些已經出現的用法

雖然目前還在實驗階段,但已經大佬做了非常多的優秀案例:

  • 遊戲 UI(HTML 寫界面 + Canvas 渲染)
  • 數據可視化(圖表 + HTML 標籤)
  • 海報生成(直接導出)
  • WebGL / 3D UI(HTML 作為紋理)
  • 設計工具(富文本 + 實時渲染)

一大波案例展示:

官方案例源碼https://github.com/WICG/html-in-canvas/tree/main/Examples

寫在最後

HTML-in-Canvas 不一定會立刻改變日常開發,但它提供了一種新的可能:

用 HTML 寫界面,用 Canvas 驅動渲染。

如果你在做可視化遊戲或 WebGL,這個方向值得多留意。

感興趣的話,可以開個 flag 試一試,感受一下這種“有點不一樣”的前端渲染方式。

  • 提案說明https://wicg.github.io/html-in-canvas/
  • Github 地址https://github.com/WICG/html-in-canvas/