5P by GN⁺ 1일전 | ★ favorite | 댓글 1개
  • HTML-in-Canvas는 웹에서 <canvas> 요소 내에 HTML 요소/콘텐츠를 직접 그릴 수 있는 새로운 표준 API를 제안하는 WICG 프로젝트임
  • 복잡한 텍스트 레이아웃, 접근성, 인터내셔널라이제이션, 품질/성능 문제를 해결하기 위해 등장했으며, 차트·UI·게임 메뉴 등 다양한 Canvas 활용 케이스에서 HTML 스타일링을 직접 활용 가능
  • drawElement, texElement2D, setHitTestRegions 등의 신규 메서드를 통해 HTML 요소를 Canvas 2D 또는 WebGL 컨텍스트에 그대로 렌더링 및 텍스처화 가능
  • 상호작용 영역, 접근성 개선, 3D 장면 내 2D UI, CSS/HTML 기반 레이아웃 등 실질적 웹앱 개발자 니즈 반영
  • 현재 Chrome Canary(138.0.7175.0 이상)에서 실험적 플래그로 활성화 가능하며, 주요 피드백·버그 리포트 환영

개요 및 중요성

  • HTML 요소를 직접적으로 <canvas>에 그릴 수 있는 새로운 API를 제안
  • 기존에는 복잡한 레이아웃 및 텍스트, HTML 기반 콘텐츠를 <canvas>에 쉽게 렌더링하는 방법이 부재해, 접근성·국제화·퍼포먼스·품질 측면에서 한계가 있었음
  • HTML-in-Canvas는 이러한 보완책으로, 2D 캔버스 및 WebGL 내에서 HTML 렌더링을 지원해, 차트 도구, 리치 텍스트 상자, 게임 UI 등 다양한 영역에서의 적용성을 높임.

활용 사례

  • 스타일이 적용된 텍스트 및 레이아웃 콘텐츠의 캔버스 내 표현
    • 예: 차트의 범례, 축, 리치 에디터 상자, 게임 내 메뉴 등
  • 접근성 강화
    • 기존 캔버스의 대체 콘텐츠와 실제 렌더링된 내용의 불일치 문제 해소
    • 새 API로 접근성 정보의 싱크 맞춤 가능
  • HTML와 WebGL 셰이더의 결합
    • CSS filter 효과를 넘어, 일반 WebGL 셰이더와 HTML의 결합 니즈 대응
  • 3D 컨텍스트 내 HTML 렌더링
    • 게임/사이트의 3D 영역에 리치 2D 콘텐츠 삽입 가능

제안 API 및 주요 기능

  • <canvas layoutsubtree> 속성으로 canvas 하위 HTML 요소의 레이아웃 활성화(단, 기본적으로 시각적으로만 렌더, 페이지 탐색 등 UA 알고리즘엔 비노출)
  • CanvasRenderingContext2D.drawElement(element, x, y, options)
    • canvas의 자식 HTML 요소를 지정 위치에 렌더링
    • options.allowReadback로 개인정보 유출 방지 제어(향후 tainting 정책 적용)
    • dwidth/dheight 파라미터로 원하는 사이즈로 리사이즈 가능
  • WebGLRenderingContext.texElement2D(...)
    • 지정 HTML 요소를 WebGL 텍스처로 직접 그려 3D 씬에 활용
  • setHitTestRegions
    • 특정 영역에 그려진 요소와 캔버스 이벤트(hit test)를 연동하여, 마우스/터치 이벤트를 자동 리다이렉트
  • fireOnEveryPaint 옵션(ResizeObserver)
    • HTML 변경/재배치 시 canvas의 리렌더 타이밍을 자동 감지해 재그리기 트리거

동작 및 한계

  • drawElement 호출 시, canvas transform matrix(CTM) 반영, 요소의 border box 내에만 이미지 클립
  • canvas에 그려진 이미지는 정적(렌더 이후 요소가 변하면 다시 drawElement 필요)
  • 오프스크린/DOM에 없는 canvas에는 미지원(기술적 한계)
  • 상호작용 요소(버튼, 폼 등)는 그릴 수 있으나, 자동으로 상호작용되지는 않음
  • 크로스오리진 iframe, SVG foreignObject 등은 미지원
  • 접근성, 보안·프라이버시(PII) 관련 이슈가 계속 논의 중

데모 예시

  • complex-text 예시: canvas 위에 HTML 스타일 텍스트, 박스 등 복잡한 레이아웃을 drawElement로 직접 그리기
  • webGL 예시: texElement2D로 HTML 콘텐츠를 WebGL 텍스처로 만들어 3D 큐브에 맵핑
  • text-input 예시: setHitTestRegions, fireOnEveryPaint를 활용해 입력 폼 등 상호작용 가능 영역 표시

개발자 트라이얼 및 유의사항

  • Chrome Canary에서 --enable-blink-features=CanvasDrawElement 플래그로 활성화
  • 캔버스 내용이 tainted 되지 않으므로 개인정보 유출 주의 필수
  • API 및 동작은 계속 변화 중이며, 대규모 HTML 테스트 사례는 아직 부족
  • 피드백 환영: 호환성, 렌더링 실패 사례, 접근성 문제 등 GitHub Issue로 제보 권장

활용 가치 및 전망

  • 차트, 데이터 비주얼라이제이션, in-canvas UI, 3D 게임 내 HUD/메뉴 등 다양한 분야에서 웹의 표현력·생산성 향상
  • 기존에는 복잡했던 HTML→Canvas 변환(스타일, 레이아웃, 다국어 지원, 접근성)을 표준 API로 직접 처리 가능
  • 웹 기반 그래픽·게임·앱 개발자들에게 강력한 신기술로 기대
Hacker News 의견
  • 접근성과 남용에 대한 많은 걱정이 있지만, 이 논의의 또 다른 면을 볼 필요가 있음
    최근 트위터에서 흥미로운 스레드를 봤는데, 웹의 발전에 있어 폰트 렌더링과 메트릭스를 JS에서 사용할 수 없어서 90%의 좋은 일들이 일어나지 못한다고 함
    웹이 텍스트를 표현하기 위해 설계된 플랫폼인데, 텍스트를 디테일하게 다룰 기능이 없다는 지적, tldraw에서 텍스트 측정을 억지로 구현해야 하는 게 안타깝다는 반응 등 다양한 답변이 있었음 (트위터 스레드: https://x.com/_chenglou/status/1951481453046538493)
    웹은 애플리케이션 개발 플랫폼이기 때문에 쉽고 강력하게 만드는 일이 모두에게 좋음
    내 생각엔 웹 API는 좀 더 로우 레벨로 내려가야 한다고 보는데, 캔버스용 폰트/텍스트 메트릭스 API가 있다면 매우 좋을 것임
    하지만 동시에 웹엔진의 텍스트 레이아웃은 엄청나게 성능이 뛰어나니, 이런 기능이 캔버스 내부에서도 쓰일 수 있다면 멋진 기능이 생겨날 것임
    내가 수년간 계속 되짚어온 사례는 ‘페이지네이션이 된 리치텍스트 에디팅’인데, contenteditable만으로는 제품 수준의 구현이 불가능하기 때문에 Google Docs가 자체 레이아웃 엔진을 만든 것임
    이 제안이 적용된다면 contenteditable의 강력함과, 페이지/프린트 레이아웃 제어 가능성을 모두 가져갈 수 있음
    이 기능이 브라우저에 적용되길 바람

    • “웹에서 일어날 수 있는 대다수 좋은 일들이 폰트 렌더링 및 메트릭스 접근이 안돼서 불가능하다”는 주장에 좀 의문이 있음
      실제 대표적인 혁신적인 사례가 뭔지 보고 싶음
      지금도 JS에서 폰트와 메트릭스 정보가 꽤 제공되고 있고, 필요한 기능은 대부분 성능에 심각한 장애 없이 우회할 수 있음
      또, HTML-in-Canvas에서 제공되는 기능이 이런 부분에서 근본적인 변화를 주는 것도 아님

    • 나도 Google Docs처럼 Nutrient에서 Harfbuzz와 자체 레이아웃 엔진을 WASM 기반으로 사용하고 있음
      데모: https://document-authoring-demo.nutrient.io/
      이런 API가 플랫폼에 공식 제공된다면 훨씬 개발이 쉬워질 것임
      WASM 덕분에 정말 막다른 길은 아님
      ElectricSQL에서 동기화 작업 중이라는 소식을 들었으니 Oleksii에게도 안부 전함

    • “이 기능이 브라우저에 적용되길 바란다”는 말에, 세상에서 가장 비효율적인 레이아웃/UI 엔진을 캔버스에까지 확장시키길 바라는 이유를 모르겠음
      이렇게 되면 오히려 좋은 API 접근권이 없는 현재의 문제만 고착화시킬 뿐임
      Figma는 DOM의 한계를 극복하려고 브라우저 안에 또 다른 브라우저를 만드는 방식으로 동작함 (참고: https://figma.com/blog/building-a-professional-design-tool-on-the-web/)
      contenteditable만으로는 제품 수준 구현이 되지 않아 Google Docs가 자체 엔진을 만들었다면, 새 제안이 리치텍스트 레이아웃에 실질적으로 도움이 되기는 어려움

  • 이 기능은 유용성이 크다고 생각하지만, HTML 안에서 Canvas 안에 HTML을 넣는 구조 자체가 뭔가 기묘하고 어울리지 않는 느낌이 듦
    내가 생각하기에, 캔버스가 브라우저에서 독립적인 1급 포맷이 되어야 붙임성 있게 다뤄질 수 있다고 봄
    그러면 HTML 중심의 페이지에 Canvas를 넣거나, 반대로 Canvas 중심에 HTML 요소가 들어가는 구조도 자연스러울 것임
    물론 이건 내 생각일 뿐임

    • 네 얘기에 전혀 이상함이 없음
      참고로, 이미 HTML을 SVG 안, 다시 HTML 안 등으로 넣을 수 있음
      만약 캔버스가 페이지의 최상위 요소라면, 페이지의 제목은 어디 저장하냐?
      결국 <title> 태그를 써야 하니, 예시로

      <!doctype html>
      <title>My canvas site</title>
      <canvas style="fill all">
      

      실질적으로 캐번스 태그 안에 콘텐츠가 들어갈 수 있게 만들면 심플하게 해결될 수 있음

      <canvas type="html">
        <h1>Canvassing</h1>
      </canvas>
      
    • 캔버스 중심 웹사이트는 불편함이 많음
      시스템 서비스(자동완성, 접근성 등) 전체를 사용할 수 없고, 개인정보 문제도 있음
      예를 들어 시스템의 맞춤법 사전 교정 기능을 쓰기 어렵고, 시스템의 접근성도 제공하지 못해서 각 앱마다 전혀 다른 UI 접근성을 직접 구현해야 함

    • 네가 말한 구조라면 플래시를 발명한 셈임
      다만, 플래시를 웹에 넣는 것도 엄청난 고생이었음

    • HTML 페이지에 Canvas를 두고, 그 안의 텍스트에 레이아웃이나 스타일링을 추가하고 싶을 때가 있음
      그렇다고 해서 전체 페이지 레이아웃 방식까지 바꾸는 건 불필요하게 복잡한 일임

    • 이전에 사람들이 WASM의 DOM 접근에 반대한 적이 있었음
      그래서 이런 방향성의 발전이 필연적이라고 봄

  • 이제 우리는 브라우저 전체를 WASM으로 컴파일해서, 이 브라우저를 메인 브라우저의 캔버스 요소 안에서 돌리는 시점까지 온 것임

  • https://github.com/WICG/html-in-canvas/… 에 보면
    ‘지문 수집(fingerprinting) 위험성’에 대해 더 추가해야 한다는 TODO가 있음

    • 실제로 텍스트를 찾아봤는데, 해당 내용은 정말로 문서에 아직 추가되어야 하는 상태임 ("TODO: Don't be evil"과 교차 참조될 수도 있을 것임)
  • SVG의 foreignObject 태그를 활용하면 이미 HTML-in-Canvas와 비슷한 결과를 얻을 수 있다는 생각임
    예를 들어 https://github.com/zumerlab/snapdom 처럼, DOM을 inlined style로 복사해서 SVG의 foreignObject 안에 넣고, 이를 캔버스로 렌더하는 프로젝트가 있음

    • 이번 제안은 foreignObject를 더 쉽게 캔버스에 그릴 수 있도록 한 것과 비슷함
      게다가, 콘텐츠가 바뀔 때 캔버스를 자동으로 업데이트하거나, 상호작용성 등 새로운 기능도 지원함
  • 혹시 내가 틀렸는지 모르겠지만, 순정 JS만으로도 캔버스 위에 HTML을 렌더링하는 건 충분히 가능하다고 느낌
    캔버스는 HTML로 할 수 없는 걸 그릴 때 쓰는 것이고, DOM을 대체할 목적이 아닌 구조임

    • 현재로서는 예를 들면

      1. 박물관 동상 3D 모델을 보여주는 경우
      2. 모델 위에 주목해야 할 특징에 주석(annotations)을 달아야 하는데, 이때 그 주석이 단순한 단어나 숫자 이상이라면
        주석이 3D 모델 뒤에 가려져야 하는데, HTML만으로는 이 처리가 무척 힘들고, 복잡한 위치 계산과 프레임 지연 등 이슈가 있음
        HTML 캔버스 위에 덧씌우면 전체 주석 요소를 한 번에 보여주거나 숨기는 정도 밖에 불가능했음
        3D 텍스트나 SDF 방식 등 별도 렌더링 시스템을 만들면, 접근성도 빠지고 모든 것을 직접 다시 구현해야 했음
        복잡한 UI(동영상, 리스트, 셀렉트박스 등)는 HTML로 다시 돌아가야 했음
    • HTML 요소가 캔버스 위 모든 것보다 앞에 있다면 괜찮지만, 그렇지 않은 경우엔 html 위에 또 캔버스를 깔아야 하고, z-레이어마다 반복작업임
      이번 변화로 마침내 브라우저의 “역전된 렌더링 레이어 스택”을 고칠 수 있다고 봄
      모든 브라우저 렌더링이 유니버설 캔버스 API 위에 쌓여야 한다고 생각함

  • 곧 우리는 HTML-in-Canvas 안에서도 다시 Canvas 렌더링을 하는 일이 필요하지 않을까 싶은 생각이 듦

    • 만약 중첩된 canvas가 같은 방식을 사용한다면 이미 동작 가능함
      다만 순환 참조는 아니고, 진짜 순환되는 canvas를 원하면 부모 canvas 내용을 수동으로 자식 canvas에 그릴 필요가 있음
  • Pimp My Ride 밈이 떠오를 정도임
    “형, 네가 HTML 좋아한다길래, 캔버스 안에 HTML을 넣어서 HTML 안에 또 캔버스를 넣어줬어”라는 느낌임

  • 다음과 같이 body 엘리먼트에 플래그를 하나 주는 건 어떨까 생각이 듦

    <body canvas="true"></body>
    

    이러면 페이지 전체가 캔버스와 같은 드로잉 서피스가 되고, 평소처럼 DOM 요소를 렌더할 수 있음
    내부적으로 DOM까지 래스터라이즈하는 과정을 오픈해주면 더 나을 것도 같음
    아키텍처 상 DOM 렌더링과 캔버스 렌더링이 완전히 대등한 레이어가 됨
    예를 들어 페이지에 선을 긋는 액션이 DOM 요소의 리플로우를 유도하거나 무시하도록 제어할 수도 있음

    • 스크린리더가 모두 동시에 비명을 지를 상황이 떠오름

    • 이 방식이면 캔버스가 자동으로 크기 조정도 가능해질 수 있는데, 만약 그렇다면 HTML 조합의 새로운 시대를 여는 것임
      iframe을 뛰어넘을 수 있음

  • 어색하긴 하지만 이번 제안에 찬성하는 편임
    어떤 걸 그려야 할 때, 기존의 HTML 엘리먼트를 재활용할 일이 종종 있음
    예전에는 그걸 오프스크린에서 비트맵으로 렌더링해서 캔버스에 복사하거나, z-index와 position absolute로 조정하려 해도 캔버스가 무조건 시각적으로 덮어버리는 문제가 있었음(최근엔 꽤 개선됨)
    이 방식이 완벽한 해결은 아닐 수 있지만, 이전의 꼼수들보다는 한결 낫다고 생각함
    딱 html2canvas처럼, 꼭 그렇게 해야 할 상황이면 쓸 만한 해법임