Una descripción práctica de CSS Houdini
Publicado: 2022-03-10Se necesita mucho tiempo para que una nueva característica o mejora de CSS progrese desde un borrador inicial hasta una característica de CSS estable y totalmente compatible que los desarrolladores pueden usar. Los polyfills basados en JavaScript se pueden usar como un sustituto de la falta de soporte del navegador para usar nuevas funciones de CSS antes de que se implementen oficialmente. Pero son defectuosos en la mayoría de los casos. Por ejemplo, scrollsnap-polyfill es uno de varios polyfills que se pueden usar para corregir las inconsistencias de soporte del navegador para la especificación CSS Scroll Snap. Pero incluso esa solución tiene algunas limitaciones, errores e inconsistencias.
La desventaja potencial de usar polyfills es que pueden tener un impacto negativo en el rendimiento y son difíciles de implementar correctamente. Este inconveniente está relacionado con el DOM y el CSSOM del navegador. El navegador crea un DOM (Modelo de objetos de documento) a partir del marcado HTML y, de manera similar, creó CSSOM (Modelo de objetos CSS) a partir del marcado CSS. Estos dos árboles de objetos son independientes entre sí. JavaScript funciona en DOM y tiene un acceso muy limitado a CSSOM.
Las soluciones JavaScript Polyfill se ejecutan solo después de que se haya completado el ciclo de procesamiento inicial, es decir, cuando se hayan creado DOM y CSSOM y el documento haya terminado de cargarse. Después de que Polyfill realiza cambios en los estilos en el DOM (incrustándolos), hace que el proceso de renderizado se ejecute nuevamente y toda la página se vuelve a renderizar. El impacto negativo en el rendimiento se vuelve aún más evidente si se basan en el método requestAnimationFrame
o dependen de las interacciones del usuario, como los eventos de desplazamiento.
Otro obstáculo en el desarrollo web son las diversas restricciones impuestas por los estándares CSS . Por ejemplo, solo hay un número limitado de propiedades CSS que se pueden animar de forma nativa. CSS sabe cómo animar colores de forma nativa, pero no sabe cómo animar degradados. Siempre ha existido la necesidad de innovar y crear experiencias web impresionantes superando los límites a pesar de las limitaciones tecnológicas. Es por eso que los desarrolladores a menudo tienden a gravitar hacia el uso de soluciones alternativas menos que ideales o JavaScript para implementar estilos y efectos más avanzados que actualmente no son compatibles con CSS, como diseño de mampostería, efectos 3D avanzados, animación avanzada, tipografía fluida, gradientes animados, elementos select
con estilo, etc.
Parece imposible que las especificaciones de CSS se mantengan al día con las diversas demandas de características de la industria, como más control sobre las animaciones, truncamiento de texto mejorado, mejor opción de estilo para elementos de input
y select
, más opciones de display
, más opciones de filter
, etc.
¿Cuál podría ser la posible solución? Ofrezca a los desarrolladores una forma nativa de extender CSS utilizando varias API . En este artículo, veremos cómo los desarrolladores frontend pueden hacer eso usando las API de Houdini, JavaScript y CSS. En cada sección, examinaremos cada API individualmente, comprobaremos la compatibilidad con su navegador y el estado actual de las especificaciones, y veremos cómo se pueden implementar hoy mediante la mejora progresiva.
¿Qué es Houdini?
Houdini, un término general para la colección de API de navegador, tiene como objetivo aportar mejoras significativas al proceso de desarrollo web y al desarrollo de estándares CSS en general. Los desarrolladores podrán ampliar el CSS con nuevas funciones usando JavaScript, conectarse al motor de renderizado de CSS y decirle al navegador cómo aplicar CSS durante un proceso de renderizado. Esto dará como resultado un rendimiento y una estabilidad significativamente mejores que el uso de polirellenos regulares.
La especificación de Houdini consta de dos grupos de API: API de alto nivel y API de bajo nivel .
Las API de alto nivel están estrechamente relacionadas con el proceso de representación del navegador (estilo → diseño → pintura → compuesto). Esto incluye:
- API de pintura
Un punto de extensión para el paso de representación de pintura del navegador donde se determinan las propiedades visuales (color, fondo, borde, etc.). - API de diseño
Un punto de extensión para el paso de representación del diseño del navegador donde se determinan las dimensiones, la posición y la alineación del elemento. - API de animación
Un punto de extensión para el paso de representación compuesta del navegador donde las capas se dibujan en la pantalla y se animan.
Las API de bajo nivel constituyen la base de las API de alto nivel. Esto incluye:
- API de modelo de objetos con tipo
- API de propiedades y valores personalizados
- API de métricas de fuentes
- Hojas de trabajo
Algunas API de Houdini ya están disponibles para su uso en algunos navegadores con otras API para hacer lo mismo cuando estén listas para su lanzamiento.
El futuro de CSS
A diferencia de las especificaciones de funciones de CSS regulares que se han introducido hasta ahora, Houdini se destaca al permitir que los desarrolladores amplíen el CSS de una manera más nativa. ¿Significa esto que las especificaciones de CSS dejarán de evolucionar y no se lanzarán nuevas implementaciones oficiales de las características de CSS? Bueno, ese no es el caso. El objetivo de Houdini es ayudar al proceso de desarrollo de características de CSS al permitir que los desarrolladores creen prototipos funcionales que se puedan estandarizar fácilmente.
Además, los desarrolladores podrán compartir los Worklets de CSS de código abierto más fácilmente y con menos necesidad de corregir errores específicos del navegador.
API de modelo de objetos con tipo
Antes de que se introdujera Houdini, la única forma en que JavaScript interactuaba con CSS era analizando CSS representado como valores de cadena y modificándolos. Analizar y anular estilos manualmente puede ser difícil y propenso a errores debido a que el tipo de valor debe cambiarse de un lado a otro y la unidad de valor debe agregarse manualmente al asignar un nuevo valor.
selectedElement.style.fontSize = newFontSize + "px"; // newFontSize = 20 console.log(selectedElement.style.fontSize); // "20px"
La API del modelo de objetos tipificados (OM tipificado) agrega más significado semántico a los valores CSS al exponerlos como objetos JavaScript tipificados. Mejora significativamente el código relacionado y lo hace más eficiente, estable y mantenible. Los valores CSS están representados por la interfaz CSSUnitValue
que consta de un valor y una propiedad de unidad.
{ value: 20, unit: "px" }
Esta nueva interfaz se puede utilizar con las siguientes propiedades nuevas:
-
computedStyleMap()
: para analizar estilos computados (no en línea). Este es un método de elemento seleccionado que debe invocarse antes de analizar o usar otros métodos. -
attributeStyleMap
: para analizar y modificar estilos en línea. Esta es una propiedad que está disponible en un elemento seleccionado.
// Get computed styles from stylesheet (initial value) selectedElement.computedStyleMap().get("font-size"); // { value: 20, unit: "px"} // Set inline styles selectedElement.attributeStyleMap.set("font-size", CSS.em(2)); // Sets inline style selectedElement.attributeStyleMap.set("color", "blue"); // Sets inline style // Computed style remains the same (initial value) selectedElement.computedStyleMap().get("font-size"); // { value: 20, unit: "px"} // Get new inline style selectedElement.attributeStyleMap.get("font-size"); // { value: 2, unit: "em"}
Observe cómo se utilizan tipos de CSS específicos al establecer un nuevo valor numérico. Al usar esta sintaxis, se pueden evitar muchos problemas potenciales relacionados con el tipo y el código resultante es más confiable y libre de errores.
Los métodos get
y set
son solo un pequeño subconjunto de todos los métodos disponibles definidos por Typed OM API. Algunos de ellos incluyen:
-
clear
: elimina todos los estilos en línea -
delete
: elimina una propiedad CSS específica y su valor de los estilos en línea -
has
: devuelve un valor booleano si se establece una propiedad CSS específica -
append
: agrega un valor adicional a una propiedad que admite múltiples valores - etc
Detección de características
var selectedElement = document.getElementById("example"); if(selectedElement.attributeStyleMap) { /* ... */ } if(selectedElement.computedStyleMap) { /* ... */ }
Estado de la especificación W3C
- Borrador de trabajo: publicado para revisión por la comunidad
Compatibilidad con navegador
Google Chrome | Borde de Microsoft | Navegador Ópera | Firefox | Safari |
---|---|---|---|---|
Soportado | Soportado | Soportado | No soportado | Apoyo parcial (*) |
* compatible con "Características de la plataforma web experimental" u otro indicador de función habilitado.
Fuente de datos: ¿Ya está listo Houdini?
API de propiedades y valores personalizados
La API de propiedades y valores de CSS permite a los desarrolladores ampliar las variables de CSS agregando un tipo, un valor inicial y una herencia definida. Los desarrolladores pueden definir propiedades personalizadas de CSS registrándolas mediante el método registerProperty
, que indica a los navegadores cómo realizar la transición y manejar la reserva en caso de error.
CSS.registerProperty({ name: "--colorPrimary", syntax: "<color>", inherits: false, initialValue: "blue", });
Este método acepta un argumento de entrada que es un objeto con las siguientes propiedades:
-
name
: el nombre de la propiedad personalizada -
syntax
: le dice al navegador cómo analizar una propiedad personalizada. Estos son valores predefinidos como<color>
,<integer>
,<number>
,<length>
,<percentage>
, etc. -
inherits
: le dice al navegador si la propiedad personalizada hereda el valor de su padre. -
initialValue
: indica el valor inicial que se usa hasta que se anula y se usa como respaldo en caso de error.
En el siguiente ejemplo, se establece la propiedad personalizada de tipo <color>
. Esta propiedad personalizada se utilizará en la transición de degradado. Podría estar pensando que el CSS actual no admite transiciones para degradados de fondo y estaría en lo correcto. Observe cómo la propiedad personalizada en sí se usa en transition
, en lugar de una propiedad de background
que se usaría para las transiciones regulares background-color
.
.gradientBox { background: linear-gradient(45deg, rgba(255,255,255,1) 0%, var(--colorPrimary) 60%); transition: --colorPrimary 0.5s ease; /* ... */ } .gradientBox:hover { --colorPrimary: red /* ... */ }
El navegador no sabe cómo manejar la transición de degradado, pero sabe cómo manejar las transiciones de color porque la propiedad personalizada se especifica como tipo <color>
. En un navegador compatible con Houdini, se producirá una transición de degradado cuando se desplace el cursor sobre el elemento. El porcentaje de posición del degradado también se puede reemplazar con una propiedad personalizada de CSS (registrada como tipo <percentage>
) y se puede agregar a una transición de la misma manera que en el ejemplo.
Si se elimina registerProperty
y se registra una propiedad personalizada de CSS regular en un selector :root
, la transición de degradado no funcionará. Se requiere que se use registerProperty
para que el navegador sepa que debe tratarlo como color.
En la implementación futura de esta API, sería posible registrar una propiedad personalizada directamente en CSS.
@property --colorPrimary { syntax: "<color>"; inherits: false; initial-value: blue; }
Ejemplo
Este sencillo ejemplo muestra el color degradado y la transición de posición en un evento de desplazamiento mediante propiedades personalizadas de CSS registradas para el color y la posición, respectivamente. El código fuente completo está disponible en el repositorio de ejemplo.

Detección de características
if (CSS.registerProperty) { /* ... */ }
Estado de la especificación W3C
- Borrador de trabajo: publicado para revisión por la comunidad
Compatibilidad con navegador
Google Chrome | Borde de Microsoft | Navegador Ópera | Firefox | Safari |
---|---|---|---|---|
Soportado | Soportado | Soportado | No soportado | No soportado |
Fuente de datos: ¿Ya está listo Houdini?
API de métricas de fuentes
La API de Font Metrics aún se encuentra en una etapa muy temprana de desarrollo, por lo que su especificación puede cambiar en el futuro. En su borrador actual, Font Metrics API proporcionará métodos para medir las dimensiones de los elementos de texto que se representan en la pantalla para permitir que los desarrolladores afecten la forma en que los elementos de texto se representan en la pantalla. Estos valores son difíciles o imposibles de medir con las funciones actuales, por lo que esta API permitirá a los desarrolladores crear funciones CSS relacionadas con texto y fuentes más fácilmente. El truncamiento de texto dinámico de varias líneas es un ejemplo de una de esas características.
Estado de la especificación W3C
- Colección de Ideas: ningún borrador de especificación presentado en este momento
Compatibilidad con navegador
Google Chrome | Borde de Microsoft | Navegador Ópera | Firefox | Safari |
---|---|---|---|---|
No soportado | No soportado | No soportado | No soportado | No soportado |
Fuente de datos: ¿Ya está listo Houdini?
Hojas de trabajo
Antes de pasar a las otras API, es importante explicar el concepto de Worklets. Los Worklets son scripts que se ejecutan durante el procesamiento y son independientes del entorno principal de JavaScript. Son un punto de extensión para los motores de renderizado. Están diseñados para el paralelismo (con 2 o más instancias) y son independientes de subprocesos, tienen acceso reducido al alcance global y el motor de representación los llama cuando es necesario. Los worklets solo se pueden ejecutar en HTTPS (en un entorno de producción) o en localhost (para fines de desarrollo).
Houdini presenta los siguientes Worklets para ampliar el motor de renderizado del navegador:
- Worklet de pintura - API de pintura
- Worklet de animación - API de animación
- Worklet de diseño: API de diseño
API de pintura
Paint API permite a los desarrolladores utilizar funciones de JavaScript para dibujar directamente en el fondo, el borde o el contenido de un elemento mediante el contexto de representación 2D, que es un subconjunto de HTML5 Canvas API. Paint API usa Paint Worklet para dibujar una imagen que responde dinámicamente a los cambios en CSS (cambios en las variables de CSS, por ejemplo). Cualquiera que esté familiarizado con Canvas API se sentirá como en casa con Paint API de Houdini.
Se requieren varios pasos para definir un Paint Worklet:
- Escriba y registre un Paint Worklet usando la función
registerPaint
- Llame al Worklet en un archivo HTML o en un archivo JavaScript principal usando la función
CSS.paintWorklet.addModule
- Use la función
paint()
en CSS con un nombre de Worklet y argumentos de entrada opcionales.
Echemos un vistazo a la función registerPaint
que se utiliza para registrar un Paint Worklet y definir su funcionalidad.
registerPaint("paintWorketExample", class { static get inputProperties() { return ["--myVariable"]; } static get inputArguments() { return ["<color>"]; } static get contextOptions() { return {alpha: true}; } paint(ctx, size, properties, args) { /* ... */ } });
La función registerPaint
consta de varias partes:
-
inputProperties
:
Una matriz de propiedades personalizadas de CSS de las que el Worklet hará un seguimiento. Esta matriz representa las dependencias de un worklet de pintura. -
inputArguments
:
Una matriz de argumentos de entrada que se pueden pasar desde la función depaint
desde el interior del CSS. -
contextOptions
: permite o no permite la opacidad de los colores. Si se establece enfalse
, todos los colores se mostrarán con opacidad total. -
paint
: la función principal que proporciona los siguientes argumentos:-
ctx
: contexto de dibujo 2D, casi idéntico al contexto de dibujo 2D de Canvas API. -
size
: un objeto que contiene el ancho y la altura del elemento. Los valores están determinados por el proceso de representación del diseño. El tamaño del lienzo es el mismo que el tamaño real del elemento. -
properties
: variables de entrada definidas eninputProperties
-
args
: una matriz de argumentos de entrada pasados en la función depaint
en CSS
-
Una vez registrado el Worklet, debe invocarse en el archivo HTML simplemente proporcionando una ruta al archivo.

CSS.paintWorklet.addModule("path/to/worklet/file.js");
Cualquier Worklet también se puede agregar desde una URL externa (desde una red de entrega de contenido, por ejemplo), lo que los hace modulares y reutilizables.
CSS.paintWorklet.addModule("https://url/to/worklet/file.js");
Después de llamar al Worklet, se puede usar dentro de CSS usando la función de paint
. Esta función acepta el nombre registrado del Worklet como primer argumento de entrada y cada argumento de entrada que le sigue es un argumento personalizado que se puede pasar a un Worklet (definido dentro de los argumentos de entrada de inputArguments
). A partir de ese momento, el navegador determina cuándo llamar al Worklet y qué acciones de usuario y propiedades personalizadas de CSS cambian para responder.
.exampleElement { /* paintWorkletExample - name of the worklet blue - argument passed to a Worklet */ background-image: paint(paintWorketExample, blue); }
Ejemplo
El siguiente ejemplo muestra la API de Paint y la reutilización y modularidad general de Worklet. Utiliza el Worklet ondulado directamente desde el repositorio de Google Chrome Labs y se ejecuta en un elemento diferente con diferentes estilos. El código fuente completo está disponible en el repositorio de ejemplos.

Detección de características
if ("paintWorklet" in CSS) { /* ... */ } @supports(background:paint(paintWorketExample)){ /* ... */ }
Estado de la especificación W3C
- Recomendación candidata: borrador de trabajo estable listo para su implementación
Compatibilidad con navegador
Google Chrome | Borde de Microsoft | Navegador Ópera | Firefox | Safari |
---|---|---|---|---|
Soportado | Soportado | Soportado | No soportado | No soportado |
Fuente de datos: ¿Ya está listo Houdini?
API de animación
La API de animación amplía las animaciones web con opciones para escuchar varios eventos (desplazamiento, desplazamiento, clic, etc.) y mejora el rendimiento mediante la ejecución de animaciones en su propio hilo dedicado mediante un Worklet de animación. Permite que la acción del usuario controle el flujo de animación que se ejecuta de manera eficaz y sin bloqueos.
Como cualquier Worklet, Animation Worklet debe registrarse primero.
registerAnimator("animationWorkletExample", class { constructor(options) { /* ... */ } animate(currentTime, effect) { /* ... */ } });
Esta clase consta de dos funciones:
-
constructor
: llamado cuando se crea una nueva instancia. Se utiliza para la configuración general. -
animate
: la función principal que contiene la lógica de animación. Proporciona los siguientes argumentos de entrada:-
currentTime
: el valor de tiempo actual de la línea de tiempo definida -
effect
: una serie de efectos que utiliza esta animación
-
Una vez registrado el Worklet de animación, debe incluirse en el archivo JavaScript principal , debe definirse la animación (elemento, fotogramas clave, opciones) y se crea una instancia de la animación con la línea de tiempo seleccionada. Los conceptos básicos de la línea de tiempo y la animación web se explicarán en la siguiente sección.
/* Include Animation Worklet */ await CSS.animationWorklet.addModule("path/to/worklet/file.js");; /* Select element that's going to be animated */ const elementExample = document.getElementById("elementExample"); /* Define animation (effect) */ const effectExample = new KeyframeEffect( elementExample, /* Selected element that's going to be animated */ [ /* ... */ ], /* Animation keyframes */ { /* ... */ }, /* Animation options - duration, delay, iterations, etc. */ ); /* Create new WorkletAnimation instance and run it */ new WorkletAnimation( "animationWorkletExample" /* Worklet name */ effectExample, /* Animation (effect) timeline */ document.timeline, /* Input timeline */ {}, /* Options passed to constructor */ ).play(); /* Play animation */
Mapeo de línea de tiempo
La animación web se basa en líneas de tiempo y la asignación de la hora actual a una línea de tiempo de la hora local de un efecto . Por ejemplo, echemos un vistazo a una animación lineal repetitiva con 3 fotogramas clave (inicio, medio, último) que se ejecuta 1 segundo después de que se carga una página (retraso) y con una duración de 4 segundos.
La línea de tiempo del efecto del ejemplo se vería así (con una duración de 4 segundos sin demora):
Línea de tiempo del efecto (duración 4s) | Fotograma clave |
---|---|
0ms | Primer fotograma clave: comienza la animación |
2000ms | Fotograma clave central: animación en curso |
4000ms | Último fotograma clave: la animación finaliza o se restablece al primer fotograma clave |
Para comprender mejor effect.localTime
, al establecer su valor en 3000ms (teniendo en cuenta el retraso de 1000ms), la animación resultante se bloqueará en un fotograma clave medio en la línea de tiempo efectiva (1000ms de retraso + 2000ms para un fotograma clave medio). El mismo efecto ocurrirá al establecer el valor en 7000ms y 11000ms porque la animación se repite en un intervalo de 4000ms (duración de la animación).
animate(currentTime, effect) { effect.localTime = 3000; // 1000ms delay + 2000ms middle keyframe }
No se produce ninguna animación cuando se tiene un valor de effect.localTime
constante porque la animación está bloqueada en un fotograma clave específico. Para animar correctamente un elemento, su effect.localTime
debe ser dinámico. Se requiere que el valor sea una función que dependa del argumento de entrada currentTime
o alguna otra variable.
El siguiente código muestra una representación funcional del mapeo 1:1 (función lineal) de una línea de tiempo para afectar la hora local.
animate(currentTime, effect) { effect.localTime = currentTime; // y = x linear function }
Línea de tiempo ( document.timeline ) | Hora local del efecto mapeado | Fotograma clave |
---|---|---|
startTime + 0ms (tiempo transcurrido) | tiempo de inicio + startTime | Primero |
startTime + 1000ms (tiempo transcurrido) | startTime + 1000ms (retraso) + 0ms | Primero |
startTime + 3000ms (tiempo transcurrido) | startTime + 1000ms (retraso) + 2000ms | Medio |
startTime + 5000ms (tiempo transcurrido) | startTime + 1000ms (retraso) + 4000ms | Último primero |
startTime + 7000ms (tiempo transcurrido) | startTime + 1000ms (retraso) + 6000ms | Medio |
startTime + 9000ms (tiempo transcurrido) | startTime + 1000ms (retraso) + 8000ms | Último primero |
La línea de tiempo no está restringida al mapeo 1:1 a la hora local del efecto. La API de animación permite a los desarrolladores manipular el mapeo de la línea de tiempo en la función animate
mediante el uso de funciones estándar de JavaScript para crear líneas de tiempo complejas. La animación tampoco tiene que comportarse igual en cada iteración (si la animación se repite).
La animación no tiene que depender de la línea de tiempo del documento, que solo comienza a contar milisegundos desde el momento en que se carga. Las acciones del usuario, como los eventos de desplazamiento, se pueden usar como una línea de tiempo para la animación mediante el uso de un objeto ScrollTimeline
. Por ejemplo, una animación puede comenzar cuando un usuario se ha desplazado a 200 píxeles y puede terminar cuando un usuario se ha desplazado a 800 píxeles en una pantalla.
const scrollTimelineExample = new ScrollTimeline({ scrollSource: scrollElement, /* DOM element whose scrolling action is being tracked */ orientation: "vertical", /* Scroll direction */ startScrollOffset: "200px", /* Beginning of the scroll timeline */ endScrollOffset: "800px", /* Ending of the scroll timeline */ timeRange: 1200, /* Time duration to be mapped to scroll values*/ fill: "forwards" /* Animation fill mode */ }); ...
La animación se adaptará automáticamente a la velocidad de desplazamiento del usuario y se mantendrá fluida y receptiva. Dado que los Animation Worklets se ejecutan fuera del hilo principal y están conectados al motor de renderizado de un navegador, la animación que depende del desplazamiento del usuario puede ejecutarse sin problemas y tener un gran rendimiento.
Ejemplo
El siguiente ejemplo muestra cómo una implementación de línea de tiempo no lineal. Utiliza la función gaussiana modificada y aplica animación de traslación y rotación con la misma línea de tiempo. El código fuente completo está disponible en el repositorio de ejemplos.

Detección de características
if (CSS.animationWorklet) { /* ... */ }
Estado de la especificación W3C
- Primer borrador de trabajo público: listo para la revisión de la comunidad, propenso a cambios en las especificaciones
Compatibilidad con navegador
Google Chrome | Borde de Microsoft | Navegador Ópera | Firefox | Safari |
---|---|---|---|---|
Apoyo parcial (*) | Apoyo parcial (*) | Apoyo parcial (*) | No soportado | No soportado |
* compatible con el indicador "Características experimentales de la plataforma web" habilitado.
Fuente de datos: ¿Ya está listo Houdini?
API de diseño
La API de diseño permite a los desarrolladores ampliar el proceso de representación del diseño del navegador mediante la definición de nuevos modos de diseño que se pueden usar en display
de la propiedad CSS. Layout API introduce nuevos conceptos, es muy complejo y ofrece muchas opciones para desarrollar algoritmos de diseño personalizados.
De manera similar a otros Worklets, el Worklet de diseño debe registrarse y definirse primero.
registerLayout('exampleLayout', class { static get inputProperties() { return ['--exampleVariable']; } static get childrenInputProperties() { return ['--exampleChildVariable']; } static get layoutOptions() { return { childDisplay: 'normal', sizing: 'block-like' }; } intrinsicSizes(children, edges, styleMap) { /* ... */ } layout(children, edges, constraints, styleMap, breakToken) { /* ... */ } });
El registro de Worklet contiene los siguientes métodos:
-
inputProperties
:
Una matriz de propiedades personalizadas de CSS de las que Worklet realizará un seguimiento que pertenece a un elemento de diseño principal, es decir, el elemento que llama a este diseño. Esta matriz representa las dependencias de un Layout Worklet. - propiedades de entrada de
childrenInputProperties
:
Una matriz de propiedades personalizadas de CSS de las que Worklet hará un seguimiento y que pertenecen a elementos secundarios de un elemento de diseño principal, es decir, los elementos secundarios de los elementos que configuran este diseño. -
layoutOptions
: define las siguientes propiedades de diseño:-
childDisplay
: puede tener un valor predefinido deblock
onormal
. Determina si los cuadros se mostrarán como bloques o en línea. -
sizing
: puede tener un valor predefinido deblock-like
omanual
. Le dice al navegador que calcule previamente el tamaño o que no lo haga (a menos que se establezca explícitamente un tamaño), respectivamente.
-
-
intrinsicSizes
: define cómo encaja una caja o su contenido en un contexto de diseño.-
children
: elementos secundarios de un elemento de diseño principal, es decir, los elementos secundarios del elemento que llama a este diseño. -
edges
: Diseño Bordes de una caja -
styleMap
: estilos OM escritos de una caja
-
-
layout
: la función principal que realiza una maquetación.-
children
: elementos secundarios de un elemento de diseño principal, es decir, los elementos secundarios del elemento que llama a este diseño. -
edges
: Diseño Bordes de una caja - Restricciones:
constraints
de un diseño principal -
styleMap
: estilos OM escritos de una caja -
breakToken
: token de interrupción utilizado para reanudar un diseño en caso de paginación o impresión.
-
Al igual que en el caso de una API de pintura, el motor de renderizado del navegador determina cuándo se llama al worklet de pintura. Solo necesita agregarse a un archivo HTML o JavaScript principal.
CSS.layoutWorklet.addModule('path/to/worklet/file.js');
Y, finalmente, debe estar referenciado en un archivo CSS.
.exampleElement { display: layout(exampleLayout); }
Cómo la API de diseño realiza el diseño
En el ejemplo anterior, exampleLayout
se definió mediante la API de diseño.
.exampleElement { display: layout(exampleLayout); }
Este elemento se denomina diseño principal y se incluye con los bordes del diseño , que consta de rellenos, bordes y barras de desplazamiento. El diseño principal consta de elementos secundarios que se denominan diseños actuales . Los diseños actuales son los elementos de destino reales cuyo diseño se puede personalizar mediante la API de diseño. Por ejemplo, al usar display: flex;
en un elemento, sus elementos secundarios se reubican para formar el diseño flexible. Esto es similar a lo que se está haciendo con la API de diseño.
Cada diseño actual consta de un diseño secundario, que es un algoritmo de diseño para LayoutChild (elemento, ::before
y ::after
pseudo-elements) y LayoutChild es un cuadro generado por CSS que solo contiene datos de estilo (sin datos de diseño). Los elementos LayoutChild son creados automáticamente por el motor de representación del navegador en el paso de estilo. Layout Child puede generar un fragmento que realmente realiza acciones de representación de diseño.
Ejemplo
De manera similar al ejemplo de Paint API, este ejemplo importa un Worklet de diseño de mampostería directamente desde el repositorio de Google Chrome Labs, pero en este ejemplo, se usa con contenido de imagen en lugar de texto. El código fuente completo está disponible en el repositorio de ejemplo.

Detección de características
if (CSS.layoutWorklet) { /* ... */ }
Estado de la especificación W3C
- Primer borrador de trabajo público: listo para la revisión de la comunidad, propenso a cambios en las especificaciones
Compatibilidad con navegador
Google Chrome | Borde de Microsoft | Navegador Ópera | Firefox | Safari |
---|---|---|---|---|
Apoyo parcial (*) | Apoyo parcial (*) | Apoyo parcial (*) | No soportado | No soportado |
* compatible con el indicador "Características experimentales de la plataforma web" habilitado.
Fuente de datos: ¿Ya está listo Houdini?
Houdini y mejora progresiva
Aunque CSS Houdini aún no tiene un soporte de navegador óptimo, se puede usar hoy con la mejora progresiva en mente. Si no está familiarizado con la mejora progresiva, valdría la pena consultar este práctico artículo que lo explica muy bien. Si decide implementar Houdini en su proyecto hoy, hay algunas cosas que debe tener en cuenta:
- Utilice la detección de características para evitar errores.
Cada API y Worklet de Houdini ofrece una forma sencilla de verificar si está disponible en el navegador. Use la detección de funciones para aplicar las mejoras de Houdini solo a los navegadores que lo admitan y evitar errores. - Úselo solo para presentaciones y mejoras visuales.
Los usuarios que navegan por un sitio web en un navegador que aún no es compatible con Houdini deben tener acceso al contenido y la funcionalidad principal del sitio web. La experiencia del usuario y la presentación del contenido no deberían depender de las funciones de Houdini y deberían tener un respaldo confiable. - Utilice un respaldo de CSS estándar.
Por ejemplo, las propiedades personalizadas de CSS normales se pueden usar como respaldo para los estilos definidos mediante la API de valores y propiedades personalizadas.
Concéntrese primero en desarrollar una experiencia de usuario del sitio web confiable y de alto rendimiento y luego use las funciones de Houdini con fines decorativos como una mejora progresiva.
Conclusión
Las API de Houdini finalmente permitirán a los desarrolladores mantener el código JavaScript utilizado para la manipulación y decoración de estilo más cerca de la canalización de representación del navegador, lo que resultará en un mejor rendimiento y estabilidad. Al permitir que los desarrolladores se conecten al proceso de representación del navegador, podrán desarrollar varios polyfills de CSS que se pueden compartir, implementar y, potencialmente, agregar a la especificación de CSS con facilidad. Houdini también hará que los desarrolladores y diseñadores estén menos restringidos por las limitaciones de CSS cuando trabajen en estilos, diseños y animaciones, lo que dará como resultado nuevas y agradables experiencias web.
Las características de CSS Houdini se pueden agregar a los proyectos hoy, pero estrictamente teniendo en cuenta la mejora progresiva. Esto permitirá que los navegadores que no son compatibles con las funciones de Houdini muestren el sitio web sin errores y ofrezcan una experiencia de usuario óptima.
Va a ser emocionante ver lo que se le ocurrirá a la comunidad de desarrolladores a medida que Houdini gane tracción y una mejor compatibilidad con los navegadores. Estos son algunos ejemplos asombrosos de los experimentos de la API de Houdini de la comunidad:
- Experimentos CSS Houdini
- Introducción interactiva a CSS Houdini
- Muestras de Houdini por Google Chrome Labs
Referencias
- Borradores de especificación W3C Houdini
- Estado de Houdini (Chrome Dev Summit 2018)
- Worklet de animación de Houdini - Google Developers
- Introducción interactiva a CSS Houdini