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

¡Llegaron las consultas de contenedores!

Tenemos buenas noticias: una de las funciones más solicitadas por los desarrolladores comenzó a implementarse en 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 contenedor son una función de CSS que te permite escribir una lógica de diseño que se oriente a componentes de un elemento superior para aplicarles diseño a sus elementos secundarios. Para crear un diseño responsivo realmente basado en componentes, consulta el tamaño de un elemento superior. Esta es una información mucho más detallada y útil que las consultas de medios, que solo proporcionan información de tamaño sobre el viewport.

ALT_TEXT_HERE

Con las consultas de contenedor, puedes escribir componentes reutilizables que pueden aparecer de forma diferente según dónde se encuentren en la página. Esto los hace mucho más resistentes 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 establecer estilos 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 unidades 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
cqw1% del ancho de un contenedor de consulta
cqhEl 1% de la altura de un contenedor de consulta
cqiEl 1% del tamaño intercalado del contenedor de consultas
cqbEl 1% del tamaño del 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 el viewport (como vh, vb, vw y vi) se pueden usar para ajustar el tamaño de cualquier elemento de 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 consulta de contenedores

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 este motivo, trabajamos para realizar mejoras en el relleno de consultas 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 está comprimido y usa ResizeObserver 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 ycqmax) en propiedades y fotogramas clave

Usa el polyfill de consulta de contenedor

Para usar el polyfill, agrega esta etiqueta de secuencia de comandos al encabezado de tu documento: :

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

También puedes usar un servicio para entregar condicionalmente el polyfill en función de User-Agent o autoalojarlo en tu propio origen.

Para obtener la mejor experiencia del usuario, te recomendamos que, en un principio, solo uses el polyfill para el contenido inferior a la mitad de la página y que utilices consultas @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 admite la anidación de 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 de writing-mode).
  • Las unidades relativas del contenedor (cqw, cqh, etcétera) 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 la consulta de contenedor expandida:
    • Sintaxis del rango (por ejemplo, (200px < width < 400px))
    • Consultas de igualdad (por ejemplo, (width = 200px))
  • Pseudoelementos, como ::before y ::after.
  • Los navegadores sin :is(...)/:where(...) son compatibles mediante una solución alternativa opcional.
  • Las consultas de funciones orientation y aspect-ratio
  • Filtrar correctamente las consultas en función de las funciones (por ejemplo, no se permite consultar height en container: inline-size 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, faltan algunas funciones que debes tener en cuenta:

  • 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 del contenedor 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 intercalado y del mismo origen. No se admiten los diseños de página de origen cruzado ni los diseños de página en iframes (a menos que se cargue un polyfill de forma manual).
  • La contención de layout y style requiere compatibilidad subyacente con el navegador:
    • Safari 15.4 o versiones posteriores
    • Por el momento, Firefox no admite el aislamiento de estilo, pero está trabajando en ello.

Advertencias

  • Para evitar afectar el FID y el 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 retrasar de manera injustificada el 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 se debe a que es probable que el tamaño de bloque de un container-type: inline-size cambie después de evaluar una consulta, pero ResizeObserver no tiene forma de decirle que no nos importan los cambios en el tamaño de 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 es intencionalmente cercana al 70%.
  • La solución alternativa de :where() es obligatoria para el 2.23% de los usuarios de navegadores anteriores a los siguientes:
    • Safari 14
    • Chromium 88
    • Edge 88
    • Samsung Internet 15
    • Firefox 78