Las consultas sobre contenedores comienzan a llegar a navegadores estables mientras se actualiza polyfill

Llegaron las consultas de contenedores.

Tenemos una noticia emocionante: ¡una de las funciones para desarrolladores más solicitadas ha empezado a llegar a los navegadores web! A partir de Chromium 105 y Safari 16, ahora puedes crear consultas de contenedores basadas en el tamaño y usar valores de unidades de consulta de contenedores en estos navegadores. Para que sea aún más fácil usar consultas de contenedores basadas en el tamaño y unidades cq, el equipo de Aurora de Chrome trabajó duro para actualizar el Polyfill de Container Query para que admita más navegadores y casos de uso, de manera que puedas sentirte seguro cuando uses esta potente función.

¿Qué son las consultas de contenedores?

Las consultas de contenedores son una función de CSS que te permite escribir lógica de diseño orientada a los componentes de un elemento superior para definir el estilo de los elementos secundarios. Puedes crear un diseño responsivo verdaderamente basado en componentes consultando el tamaño de un elemento superior. Esta es información mucho más detallada y útil que las consultas de medios, que solo proporcionan información sobre el tamaño del viewport.

ALT_TEXT_HERE

Con las consultas de contenedores, puedes escribir componentes reutilizables que pueden mostrarse de manera diferente según el lugar de la página en el que se encuentren. Esto los hace mucho más resilientes y responsivos en todas las páginas y plantillas.

Usa consultas de contenedores

Supongamos que tienes código HTML:

<!-- card parent -->
<div class=”card-parent”>
  <div class=”card>
     <!-- card contents -->
      …
  </div>
</div>

Para usar una consulta de contenedor, primero debes establecer la contención en el elemento superior del que deseas hacer un seguimiento. Para ello, configura la propiedad container-type o usa la abreviatura container para establecer el tipo y el nombre del contenedor al mismo tiempo.

.card-parent {
  /* query the inline-direction size of this parent */
  container-type: inline-size;
}

Ahora, puedes usar la regla @container para configurar diseños en función del elemento superior más cercano. Para un diseño como el de la imagen de arriba, donde una tarjeta podría ir de una columna a dos, escribe algo como:

@container (min-width: 300px) {
  .card {
    /* styles to apply when the card container (.card-parent in this case) is >= 300px */
    /* I.e. shift from 1-column to 2-column layout: */
    grid-template-columns: 1fr 1fr;
  }
}

Para ser más claro y explícito, asigna un nombre al contenedor del elemento superior:

.card-parent {
  container-type: inline-size;
  /* set name here, or write this in one line using the container shorthand */
  container-name: card-container;
}

Luego, vuelve a escribir el código anterior de la siguiente manera:

@container card-container (min-width: 300px) {
  .card {
    grid-template-columns: 1fr 1fr;
  }
}

Unidades de consulta de contenedor

Para que las consultas de contenedores sean aún más útiles, también puedes usar valores de unidad basados en contenedores. En la siguiente tabla, se muestran los posibles valores de unidad de contenedor y cómo se corresponden con el tamaño de un contenedor:

Unidaden relación con
cqwEl 1% del ancho de un contenedor de consultas
cqhEl 1% de la altura de un contenedor de consulta
cqiEl 1% del tamaño intercalado del contenedor de consultas
cqb1% del tamaño de bloque de un contenedor de consulta
cqminEl valor menor de cqi o cqb
cqmaxEl valor mayor de cqi o cqb

Un ejemplo de cómo usarías unidades basadas en contenedores es la tipografía responsiva. Las unidades basadas en viewport (como vh, vb, vw y vi) se pueden usar para ajustar el tamaño de cualquier elemento en la pantalla.

.card h2 {
  font-size: 15cqi;
}

Este código hará que el tamaño de la fuente sea el 15% del tamaño intercalado del contenedor, lo que significa que se agranda a medida que aumenta el tamaño de la línea (ancho) o que se reduce a medida que disminuye. Para llevar esto aún más lejos, usa la función clamp() para asignar un límite de tamaño mínimo y máximo a tu tipografía, y ajustar su tamaño de manera responsiva según el tamaño del contenedor:

.card h2 {
  font-size: clamp(1.5rem, 15cqi, 3rem);
}

Ahora el encabezado nunca será mayor que 3rem ni menor que .5rem, pero ocupará el 15% del tamaño intercalado del contenedor en cualquier lugar.

Esta demostración va un paso más allá y actualiza las tarjetas más anchas para que tengan un rango de tamaño más pequeño, ya que se presentan en una vista de 2 columnas.

El polyfill de la consulta del contenedor

Dado que las consultas de contenedores son una función tan poderosa, queremos que te sientas cómodo para incorporarlas en tus proyectos. Además, queremos que sepas que la compatibilidad con los navegadores es una parte importante de ello. Por esta razón, hemos estado trabajando para mejorar el Polyfill de consulta de contenedores. Este polyfill tiene compatibilidad general con los siguientes elementos:

  • Firefox 69 y versiones posteriores
  • Chrome 79 y versiones posteriores
  • Edge 79 y versiones posteriores
  • Safari 13.4 o versiones posteriores

Tiene un tamaño inferior a 9 KB cuando se comprime y usa RenameObserver con MutationObserver para admitir la sintaxis completa de la consulta @container que está disponible actualmente en navegadores estables:

  • Consultas discretas (width: 300px y min-width: 300px)
  • Consultas por rango (200px < width < 400px y width < 400px)
  • Unidades de longitud relativa del contenedor (cqw, cqh, cqi, cqb, cqmin y cqmax) en propiedades y fotogramas clave.

Usa el polyfill de consulta de contenedores

Para usar el polyfill, agrega la siguiente etiqueta de secuencia de comandos al encabezado del documento:

<script type="module">
  if (!("container" in document.documentElement.style)) {
    import("https://unpkg.com/container-query-polyfill@^0.2.0");
  }
</script>

Es posible que también quieras usar un servicio para entregar condicionalmente el polyfill basado en User-Agent o alojarlo en tu propio origen.

Para obtener la mejor experiencia del usuario, se recomienda que, inicialmente, solo uses el polyfill para el contenido de la mitad inferior de la página y las búsquedas de @supports para reemplazarlo temporalmente por un indicador de carga hasta que el polyfill esté listo para mostrarlo:

@supports not (container-type: inline-size) {
  .container,
  footer {
    display: none;
  }

  .loader {
    display: flex;
  }
}

En redes y dispositivos lo suficientemente rápidos, o dispositivos que admiten de forma nativa las consultas de contenedores, este indicador de carga nunca se mostrará.

Nuevas funciones de Polyfill

El polyfill actualizado admite lo siguiente:

  • Se anidaron @container reglas.
  • Se pueden anidar reglas @container en consultas @supports y @media, y viceversa.
  • Las CSS condicional, como @supports (container-type: inline-size), pasarán después de que se cargue el polyfill.
  • Compatibilidad total con la sintaxis de CSS (ya no hay ningún problema con colocar comentarios en cualquier lugar en el que sean sintácticamente válidos)
  • Modos de escritura vertical (a través del modo de escritura)
  • Las unidades relativas de contenedor (cqw, cqh, etc.) son compatibles con las condiciones de consulta, las declaraciones de propiedades y los fotogramas clave de animación. rem y em son compatibles con las condiciones de consulta.
  • Sintaxis de consulta expandida del contenedor:
    • Sintaxis del rango (por ejemplo, (200px < width < 400px))
    • Consultas de igualdad (por ejemplo, (width = 200px))
  • Pseudoelementos, como ::before y ::after.
  • Los navegadores sin :is(...) ni :where(...) son compatibles a través de una solución alternativa opcional.
  • Las consultas de los atributos orientation y aspect-ratio
  • Filtrar correctamente las consultas según los atributos (por ejemplo, consultar height en container: inline-size no está permitido correctamente con un modo de escritura horizontal)
  • Mutación del DOM (por ejemplo, cuando se quitan los elementos <style> y <link> durante el tiempo de ejecución)

Limitaciones y advertencias de Polyfill

Si usas el polyfill de consulta de contenedor, debes tener en cuenta algunas funciones faltantes:

  • Aún no se admite Shadow DOM.
  • Las unidades relativas de contenedor (por ejemplo, cqw y cqh) no son compatibles con las condiciones de consulta de @media.
    • Safari: Las unidades relativas de contenedores no son compatibles con los fotogramas clave de animación anteriores a la versión 15.4.
  • calc(), min(), max() y otras funciones matemáticas aún no son compatibles con las condiciones de consulta.
  • Este polyfill solo funciona con CSS intercalados y del mismo origen. No se admiten las hojas de estilo de distintos orígenes ni las hojas de estilo en iframes (a menos que un polyfill se cargue manualmente).
  • La contención de layout y style requiere compatibilidad con el navegador subyacente:
    • Safari 15.4 o versiones posteriores
    • Firefox no admite la contención de estilos en este momento, pero está trabajando en ello.

Advertencias

  • Para evitar el impacto en FID y CLS, el polyfill no garantiza cuándo se producirá el primer diseño, incluso si se carga de forma síncrona, excepto que intentará evitar un retraso injustificado del LCP. En otras palabras, nunca debes confiar en él para la primera pintura.
  • Genera ResizeObserver Loop Errors. El polyfill original también hace esto, pero vale la pena mencionarlo. Esto ocurre porque es probable que el tamaño del bloque de una container-type: inline-size cambie después de evaluar una búsqueda, pero ResizeObserver no tiene forma de indicarle que no nos preocupan los cambios de tamaño del bloque.
  • Este polyfill se probó con las pruebas de la plataforma web y alcanzó el 70% de aprobación, ya que ciertas funciones, como las APIs de JavaScript, no tienen polyfill, por lo que la tasa de aprobación se acerca intencionalmente al 70%.
  • La solución alternativa de :where() es necesaria para el 2.23% de los usuarios de navegadores anteriores a:
    • Safari 14
    • Chromium 88
    • Edge 88
    • Samsung Internet 15
    • Firefox 78