HTML-in-Canvas en Chrome 157: DOM interactivo dentro de 2D, WebGL y WebGPU

Publicado el 26 de octubre de 2026

Después de una prueba de origen exitosa, Chrome 157 marca el lanzamiento oficial de la versión estable de la API de HTML-in-Canvas. La API de HTML-in-Canvas cierra la brecha entre el mundo interactivo y accesible del DOM y el control de alto rendimiento a nivel de píxeles de <canvas>. Esta API te ofrece lo mejor de ambos mundos: funciones enriquecidas del navegador y gráficos de lienzo acelerados por GPU.

Descripción general en video de la API de HTML-in-Canvas.

El dilema de Canvas frente al DOM

Anteriormente, cuando creabas apps web con requisitos visuales exigentes, tenías que elegir entre elementos HTML estándar y contextos de lienzo sin procesar.

Tecnología Ventajas Limitaciones
<canvas> Control de píxeles de bajo nivel con acceso a la GPU para controlar canalizaciones de gráficos 2D y 3D, sombreadores personalizados y trabajadores fuera de pantalla. Renderización de alto rendimiento para IU pesadas y con gran cantidad de datos No hay funciones integradas de la plataforma web, como la selección de texto, copiar y pegar, acciones de clic con el botón derecho y ajuste de texto. La cuadrícula de píxeles opaca no admite lectores de pantalla, la función Buscar en la página, la traducción automática ni el autocompletado de forma predeterminada, y requiere una implementación de resguardo.
HTML Semantic UI lista para usar con controles de formulario integrados, tipografía responsiva y diseño CSS. Integración profunda del navegador para lectores de pantalla, Buscar en la página y Herramientas para desarrolladores Capacidad limitada para controlar el rendimiento de las IU complejas Los efectos visuales se limitan a CSS y SVG estándar sin manipulación directa de píxeles ni sombreadores.

Antes de HTML-in-Canvas

Antes de esta API, si creabas IU con muchos lienzos, tenías que elegir entre dos enfoques, cada uno con sus propias desventajas:

  1. Renderización de texto directamente como píxeles de lienzo (fillText()): Las apps dibujaban texto y controles de la IU de forma imperativa como píxeles sin procesar. Este enfoque tuvo las siguientes desventajas:
    • Desglose de accesibilidad: Los lectores de pantalla y las herramientas de accesibilidad no pueden leer los píxeles del lienzo, a menos que construyas y sincronices manualmente un DOM de resguardo invisible.
    • Pérdida de funciones del navegador: Los usuarios no pueden buscar con Buscar en la página (Ctrl/Cmd + F), copiar y pegar texto de forma natural, activar menús contextuales ni usar la traducción y el corrector ortográfico del navegador.
    • Motores de tipografía complejos: Para admitir la internacionalización, se deben empaquetar motores de diseño de JavaScript grandes.
  2. Superposiciones HTML flotantes sobre el lienzo: Por ejemplo, usar bibliotecas que posicionan elementos HTML estándar sobre el lienzo calculando cuadros delimitadores y transformaciones de matrices en JavaScript. Las desventajas de este enfoque incluyen las siguientes:
    • Retraso de sincronización y fragmentación visual: El desplazamiento, el zoom o los movimientos de la cámara en 3D pueden hacer que los elementos del DOM de superposición se desvíen o se muevan con respecto a los píxeles del lienzo debido a las diferencias en la latencia de fotogramas.
    • Limitaciones de recorte y orden Z: Las superposiciones HTML siempre se ubican en la parte superior de todo el búfer del lienzo. No era posible incorporar HTML dentro de una escena en 3D (por ejemplo, detrás de un objeto en 3D, dentro de un material de vidrio o reflejado en un espejo) sin soluciones alternativas complejas de iframe a imagen.
    • Sobrecarga de rendimiento: Para mantener las superposiciones alineadas con el lienzo, debes volver a calcular la transformación de cada superposición en JavaScript y escribirla en style.transform en cada fotograma. Luego, el navegador analiza cada cadena y vuelve a calcular el estilo del elemento antes de renderizar el fotograma, por lo que el trabajo del subproceso principal aumenta con cada superposición que agregas. En un contexto 2D, drawElementImage() actualiza la posición del elemento por ti. En WebGL y WebGPU, pasas la transformación que calculas a updateElementGeometry() como una matriz. De cualquier manera, el navegador no analiza el CSS ni vuelve a calcular los estilos.

Beneficios clave de HTML-in-Canvas

HTML-in-Canvas elimina estas desventajas. Si colocas HTML dentro del elemento <canvas>, el contenido seguirá siendo interactivo y todas las integraciones del navegador funcionarán automáticamente.

El contenido HTML renderizado dentro de un <canvas> tiene las mismas capacidades que el HTML fuera de <canvas>:

  • Diseño y formato de texto: Compatibilidad con el diseño y el formato de texto, incluido el texto de varias líneas o bidireccional con estilos CSS aplicados
  • Controles de formulario: Controles de formulario expresivos con amplias opciones de personalización de CSS y sombreadores.
  • Selección de texto, copiar y pegar, y hacer clic con el botón derecho: Los usuarios pueden destacar texto dentro de escenas en 3D o activar menús contextuales.
  • Accesibilidad: El contenido HTML renderizado dentro del lienzo se expone al árbol de accesibilidad para los lectores de pantalla.
  • Integración de funciones del navegador: Las funciones del navegador, como la traducción, el autocompletado y la búsqueda en la página, funcionan de inmediato. Los usuarios pueden traducir o buscar texto dentro de las texturas de WebGL y WebGPU.
  • Integración de extensiones: Las extensiones del navegador funcionan en el contenido. Por ejemplo, una extensión de reemplazo de texto actualiza automáticamente el texto renderizado en tus mallas 3D.
  • Integración de Herramientas para desarrolladores: Inspecciona y modifica los estilos CSS de los elementos de la IU del lienzo directamente en las Herramientas para desarrolladores de Chrome.
  • Indexabilidad y agentes de IA: Los rastreadores web y los agentes de IA pueden indexar el contenido del DOM renderizado en escenas en 2D y 3D.
  • Edición y exportación de contenido multimedia: Exporta composiciones de lienzo completas que contengan elementos del DOM en vivo directamente a imágenes (toDataURL(), toBlob()) o transmisiones de video (captureStream()).
Demostración que compara la integración de funciones del texto renderizado directamente en un lienzo y HTML-in-Canvas. En el panel HTML-in-Canvas, el contenido se puede seleccionar y traducir, y las funciones del navegador, como el autocompletado, funcionan de inmediato. En el panel de lienzo estándar, el contenido se renderiza directamente en un lienzo con el método fillText y no es interactivo.

Casos de uso principales

HTML-in-Canvas habilita funciones en varias áreas:

  • Apps grandes basadas en lienzos: Las apps web pesadas pueden renderizar componentes de la IU directamente en los espacios de trabajo de lienzo, lo que mejora la accesibilidad y reduce el tamaño del paquete.
  • Escenas y juegos en 3D: Las experiencias y los juegos inmersivos de WebXR pueden posicionar elementos interactivos del DOM, como terminales en el juego o libros en 3D legibles, directamente dentro de las escenas.
  • Edición y exportación de contenido multimedia: Las herramientas creativas que combinan tipografía HTML enriquecida con efectos de sombreado pueden exportar escenas compuestas directamente a imágenes o transmisiones de video.
  • IU expresivas: Puedes manipular el contenido HTML como píxeles sin procesar para crear efectos visuales basados en sombreadores.

Guía de inicio rápido de HTML-in-Canvas

Para renderizar HTML en un lienzo, se deben seguir estos pasos:

  1. Prepara tu lienzo. Establecer de forma declarativa los atributos correctos para que el navegador sepa que debe renderizar HTML en un lienzo Esta configuración es idéntica en los contextos de 2D, WebGL y WebGPU. Obtén más información para configurar tu lienzo y declarar elementos HTML que se dibujarán de forma independiente.

    <!-- Prepare your canvas by setting the `content` attribute -->
    <canvas id="canvas" width="600" height="400" content="drawable">
      <!-- Mark child as `drawable` to render to canvas -->
      <div id="myElement" drawable>
        <!-- Your HTML here -->
      </div>
    </canvas>
    
  2. Dibuja la imagen del elemento en el lienzo. La implementación exacta depende de si renderizas HTML en un contexto de 2D, WebGL o WebGPU.

    const ctx = canvas.getContext("2d");
    // Draw HTML element into canvas in 2D
    ctx.drawElementImage(myElement, myElementX, myElementY);
    
  3. Opcional: Sincroniza el DOM y los píxeles. La sincronización de la geometría también depende del contexto que uses. En 2D, el navegador lo controla automáticamente de forma predeterminada, mientras que, en los contextos 3D, debes construir una transformación y pasarla al método updateElementGeometry.

    // In 3D, construct a transform as needed, for example:
    const transform = new DOMMatrix().translate(x, y);
    // Synchronize the element's DOM and pixels
    canvas.updateElementGeometry(myElement, { canvasTransform: transform });
    

Compatibilidad con frameworks y ecosistemas

Las principales bibliotecas de gráficos 3D y WebGL admiten HTML-in-Canvas:

  • Three.js: Ofrece compatibilidad experimental con THREE.HTMLTexture.

    const material = new THREE.MeshBasicMaterial();
    material.map = new THREE.HTMLTexture(uiElement);
    const mesh = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), material);
    scene.add(mesh);
    
  • PlayCanvas: Admite la transmisión de texturas HTML con setSource().

    canvas.addEventListener('paint', () => {
      htmlTexture.setSource(htmlElement);
    }, { once: true });
    
  • Babylon.js: Proporciona vinculación integrada a través de BABYLON.HtmlTexture.

    const htmlTexture = new BABYLON.HtmlTexture("htmlTexture", uiElement, scene);
    material.diffuseTexture = htmlTexture;
    
  • PixiJS: Se envió compatibilidad integrada en la versión v8.19.0 con HTMLSource.

    import { HTMLSource } from 'pixi.js/html-source';
    const sprite = Sprite.from(new HTMLSource({ resource: form, autoUpdate: true }));
    app.stage.addChild(sprite);
    
  • CanvasUI: Es una biblioteca de componentes de código abierto diseñada específicamente para HTML-in-Canvas.

Para obtener más detalles sobre la implementación, consulta la documentación de cada framework.

Detección de funciones y estrategias de resguardo

Para garantizar la compatibilidad entre navegadores, verifica la compatibilidad con la API antes de ejecutar tu código:

export function supportsHtmlInCanvas() {
  if (typeof document === "undefined") return false;
  const canvas = document.createElement("canvas");
  canvas.setAttribute("content", "drawable");
  return canvas.content === "drawable";
}

Si la API no está disponible, puedes recurrir a IU alternativas, superposiciones HTML flotantes o una de las bibliotecas disponibles (por ejemplo, three-html-render, html2canvas o dom-to-image).

Próximos pasos