Desbloquea el poder de las consultas de contenedores de CSS: lecciones del equipo de Netflix

Jeremy Weeks
Jeremy Weeks
Stefan Heymanns
Stefan Heymanns

Las consultas de contenedores revolucionaron la forma en que los desarrolladores abordan el diseño responsivo, y el equipo de Netflix experimentó de primera mano el profundo impacto que pueden tener en la optimización del desarrollo, la mejora de la flexibilidad y el aumento del rendimiento. En esta publicación, se analizan los beneficios clave de usar consultas de contenedor y se comparan con métodos más antiguos, en particular, aquellos que dependen de JavaScript para el control de diseño. Incluye ejemplos de código para ilustrar cada punto y mostrar cómo las consultas de contenedores pueden facilitar mucho tu vida como desarrollador.

1. Diseño de componentes simplificado, “ascendente” en comparación con “descendente”

Uno de los cambios más significativos que experimentó el equipo de Netflix fue pasar de un enfoque de diseño “top-down” a uno “bottom-up”. Antes de las consultas de contenedores, los contenedores superiores debían conocer completamente los requisitos de diseño de sus elementos secundarios. Con las consultas de contenedor, esta lógica se invierte, lo que permite que los componentes secundarios controlen su diseño en función del tamaño de su propio contenedor. Esto simplifica el rol del elemento superior y reduce la cantidad de lógica de diseño en el código.

Ejemplo: Consultas de contenedor en comparación con consultas de medios y JavaScript

Antes (se necesita JavaScript):

/* Layout with media queries */
.card {
    width: 100%;
}

@media (min-width: 600px) {
    .card {
        width: 50%;
    }
}

@media (min-width: 900px) {
    .card {
        width: 33.33%;
    }
}
// JavaScript to detect parent container size
const container = document.querySelector('.container');
const card = document.querySelector('.card');

function adjustLayout() {
    if (window.innerWidth >= 900) {
        card.style.width = '33.33%';
    } else if (window.innerWidth >= 600) {
        card.style.width = '50%';
    } else {
        card.style.width = '100%';
    }
}

window.addEventListener('resize', adjustLayout);
adjustLayout();

Después:

/* Container Query */
.container {
    container-type: inline-size;
}

.card {
    width: 100%;
}

@container (min-width: 600px) {
    .card {
        width: 50%;
    }
}

@container (min-width: 900px) {
    .card {
        width: 33.33%;
    }
}

En este ejemplo, se muestra cómo el contenedor superior ya no necesita administrar el diseño secundario. La regla @container permite que .card reaccione al tamaño de su contenedor inmediato, lo que simplifica la lógica del diseño y elimina la necesidad de JavaScript por completo.

2. Capacidad de respuesta sin consultas de medios complejas

El equipo de Netflix descubrió cómo las consultas de contenedores simplifican la capacidad de respuesta, especialmente para el diseño centrado en dispositivos móviles. En lugar de escribir consultas de medios complejas, puedes crear componentes reutilizables que se ajusten según el tamaño de su contenedor, lo que permite diseños dinámicos en varios tamaños de pantalla y dispositivos. Esto es útil en especial para apps como Netflix, en las que predomina el tráfico móvil.

Ejemplo: Capacidad de respuesta de componentes con consultas de contenedores

Antes:

/* Desktop versus Mobile
this only works if.sidebar is directly contained by a viewport-width element */
.sidebar {
    width: 300px;
}

@media (max-width: 768px) {
    .sidebar {
        width: 100%;
    }
}

Después:

/* Responsive sidebar based on container,
.sidebar can be placed in any element of any width */
.container {
    container-type: inline-size;
}

.sidebar {
    width: 100%;
}

@container (min-width: 768px) {
    .sidebar {
        width: 300px;
    }
}

En lugar de depender de consultas de contenido multimedia basadas en el viewport, .sidebar ahora responde al tamaño del contenedor, lo que le permite adaptarse de forma más natural a los diseños dinámicos sin necesidad de conocer el tamaño del viewport o el contenedor superior.

3. Se redujo la dependencia de JavaScript para la administración de diseños.

Antes de las consultas de contenedores, muchos equipos, incluido Netflix, tenían que depender de JavaScript para los diseños dinámicos. Si consultas el tamaño de la ventana, JavaScript activaría cambios de diseño, lo que aumentaría la complejidad y el potencial de errores. Las consultas de contenedor eliminan esta necesidad, ya que permiten que CSS controle la capacidad de respuesta del diseño según el tamaño del contenedor.

Ejemplo: Cómo quitar la lógica de diseño basada en JavaScript

Antes:

const cardContainer = document.querySelector('.card-container');
const cards = cardContainer.children;

function adjustLayout() {
    if (cardContainer.offsetWidth > 900) {
        cards.forEach(card => card.style.width = '33.33%');
    } else if (cardContainer.offsetWidth > 600) {
        cards.forEach(card => card.style.width = '50%');
    } else {
        cards.forEach(card => card.style.width = '100%');
    }
}

window.addEventListener('resize', adjustLayout);
adjustLayout();

Después:

.card-container {
    container-type: inline-size;
}

.card {
    width: 100%;
}

@container (min-width: 600px) {
    .card {
        width: 50%;
    }
}

@container (min-width: 900px) {
    .card {
        width: 33.33%;
    }
}

Este enfoque no solo reduce la cantidad de JavaScript necesaria, sino que también mejora el rendimiento, ya que evita los cálculos del entorno de ejecución.

4. Menos código, menos errores

El equipo de Netflix descubrió que usar consultas de contenedor generaba menos líneas de código y menos errores relacionados con el diseño. Cuando se traslada la lógica de diseño de JavaScript a CSS y se elimina la necesidad de consultas de contenido multimedia complejas, los desarrolladores pueden escribir código más fácil de mantener.

Ejemplo: Reducción del código de diseño

El equipo de Netflix observó que, después de adoptar las consultas de contenedor, notó una reducción significativa en el código CSS, hasta un 30% en ciertos componentes. Al mismo tiempo, el equipo pudo simplificar muchas consultas de contenido multimedia complejas y, a veces, propensas a conflictos quitando la lógica que controlaba los componentes secundarios, lo que logró un mayor grado de separación de preocupaciones. Esta reducción no solo acelera el desarrollo, sino que también minimiza los posibles puntos de falla, lo que genera menos errores.

Antes:

/* Before with complex media queries */
.card {
    width: 100%;
}

@media (min-width: 600px) {
    .card {
        width: 50%;
    }
}

@media (min-width: 900px) {
    .card {
        width: 33.33%;
    }
}

Después

.container {
    container-type: inline-size;
}

.card {
    width: 100%;
}

@container (min-width: 600px) {
    .card {
        width: 50%;
    }
}

@container (min-width: 900px) {
    .card {
        width: 33.33%;
    }
}

5. Experiencia mejorada para los desarrolladores

bq. "Esto me facilitó la vida cien veces"

Quizás uno de los beneficios más subestimados de las consultas de contenedores es la mejora de la experiencia del desarrollador. Cuando el CSS se comporta de una manera más intuitiva y centrada en los componentes, los desarrolladores pueden enfocarse en compilar componentes reutilizables y flexibles sin preocuparse por cómo se comportarán en cada situación de diseño posible.

Como dijo uno de los miembros del equipo de Netflix, “Así es como debería haber funcionado CSS desde el principio”.

6. Resguardo de polyfill

Si bien las consultas de contenedores ahora están en todos los navegadores principales, existe la preocupación de que las versiones anteriores de los navegadores aún estén en uso. Un resguardo es muy importante. El equipo de Netflix usa este polyfill de JavaScript creado por colaboradores de la comunidad web. La implementación es directa con la detección de componentes:

if (! CSS.supports("container-type:size")) {
  /*use polyfill from
  https://www.npmjs.com/package/container-query-polyfill */
 }

Conclusión

Las consultas de contenedor representan un gran avance en CSS, lo que facilita a los desarrolladores la compilación de componentes flexibles y responsivos que se pueden reutilizar en diferentes partes de un sitio. Debido a que reducen la dependencia de JavaScript para el diseño, eliminan las consultas de contenido multimedia complejas y aceleran el desarrollo, ofrecen ventajas significativas en el rendimiento y la capacidad de mantenimiento. Actualmente, la mayoría de los casos de uso se encuentran en las páginas de Tudum de Netflix, con posibles planes para usar consultas de contenedores en otras partes de Netflix. El equipo de Netflix considera que las consultas de contenedores son una herramienta de primer nivel en el kit de herramientas para desarrolladores, y su uso solo se expandirá a medida que más desarrolladores adopten la flexibilidad y el poder que ofrecen. Ya sea para adaptar componentes existentes o diseñar otros nuevos, las consultas de contenedores ofrecen una ruta de acceso más simple y clara para el diseño responsivo.

Si aún no lo hiciste, prueba las consultas de contenedores. Es probable que descubras que simplifican tu flujo de trabajo de maneras que no esperabas.