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 contenedor basadas en el tamaño y usar valores de unidades de consulta de contenedor en estos navegadores. Para que sea aún más fácil usar las consultas de contenedores basadas en el tamaño y las unidades cq, el equipo de Aurora en Chrome trabajó arduamente para actualizar el polyfill de consultas de contenedores y admitir más navegadores y casos de uso, de modo que puedas usar esta función potente con confianza hoy mismo.

¿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 componentes 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 el siguiente 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, establece la propiedad container-type o usa el atajo 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 la imagen anterior, en el que una tarjeta puede ir de una columna a dos, escribe algo como lo siguiente:

@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 que sea más ordenado 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 contenedores

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 unidades 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
cqh1% de la altura de un contenedor de consulta
cqiEl 1% del tamaño intercalado de un contenedor de consulta
cqbEl 1% del tamaño del bloque de un contenedor de consulta
cqminEl valor más bajo de cqi o cqb
cqmaxEl valor más alto 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 aumentará a medida que aumente el tamaño intercalado (ancho) o disminuirá a medida que disminuya. Para llevar esto aún más lejos, usa la función clamp() para darle a tu tipografía un límite de tamaño mínimo y máximo, y ajusta su tamaño de forma 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 punto intermedio.

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.

La polyfill de consulta de contenedor

Dado que las consultas de contenedor son una función muy potente, queremos que puedas incorporarlas a tus proyectos sin problemas y sabemos que la compatibilidad con navegadores es una parte importante de eso. Por este motivo, trabajamos para realizar mejoras en el relleno de consultas de contenedores. Este polyfill tiene compatibilidad general en los siguientes navegadores:

  • Firefox 69 y versiones posteriores
  • Chrome 79 y versiones posteriores
  • Edge 79 y versiones posteriores
  • Safari 13.4 y 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 y cqmax) 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 brindar la mejor experiencia del usuario, te recomendamos que, en un principio, solo uses la polyfill para el contenido inferior a la mitad de la página y las consultas @supports para reemplazarlo temporalmente por un indicador de carga hasta que la polyfill esté lista para mostrarlo:

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

  .loader {
    display: flex;
  }
}

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

Nuevas funciones de Polyfill

El polyfill actualizado admite lo siguiente:

  • Reglas @container anidadas
  • Se admiten reglas de anidación @container en consultas @supports y @media, y viceversa.
  • El CSS condicional, como @supports (container-type: inline-size), pasará después de que se cargue el polyfill.
  • Compatibilidad total con la sintaxis CSS (ya no hay problemas para colocar comentarios en cualquier lugar que sean válidos sintácticamente).
  • Modos de escritura vertical (a través de writing-mode).
  • Las unidades relativas del contenedor (cqw, cqh, etcétera) se admiten en 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 de contenedor expandida:
    • Sintaxis de rango (por ejemplo, (200px < width < 400px)).
    • Consultas de igualdad (por ejemplo, (width = 200px)).
  • Elementos pseudo 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, elementos <style> y <link> que se quitan durante el tiempo de ejecución)

Limitaciones y advertencias de la función de reemplazo

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 @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 se admiten en 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).
  • El aislamiento de layout y style requiere compatibilidad con el navegador subyacente:
    • Safari 15.4 y 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 forma injustificada el LCP. En otras palabras, nunca debes confiar en él para la primera pintura.
  • Genera ResizeObserver Loop Errors. El polyfill original también lo hace, 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ó un 70% de aprobación, ya que algunas funciones, como las APIs de JavaScript, no tienen polyfill, por lo que el porcentaje de aprobación está intencionalmente más cerca del 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