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

Llegaron las consultas a contenedores

Tenemos una noticia emocionante: una de las funciones para desarrolladores más solicitadas ha comenzado 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 estuvo trabajando arduamente en la actualización de Container Query Polyfill para admitir más navegadores y casos de uso, de manera que pueda confiar en el uso de esta poderosa función hoy mismo.

¿Qué son las consultas de contenedores?

Las consultas de contenedores son una función de CSS que te permite escribir una lógica de diseño orientada a funciones de un elemento superior para aplicar estilo a sus elementos secundarios. Puedes crear un diseño responsivo realmente basado en componentes consultando el tamaño de un elemento superior. Esta es información mucho más detallada y útil que algo como 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 tener un aspecto diferente según el lugar en el que 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 algo de 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 principal del cual deseas realizar 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 basados en el elemento superior más cercano. Para un diseño como la imagen de arriba, en el que una tarjeta podría ir de una columna a dos columnas, 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 prolijo 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 como:

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

Unidades de consulta de contenedores

Para que las consultas de contenedor 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 unidades 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 consultas
cqiEl 1% del tamaño intercalado de un contenedor de consultas
cqbEl 1% del tamaño de bloque de un contenedor de consultas
cqminEl valor menor de cqi o cqb
cqmaxEl valor más alto de cqi o cqb

Un ejemplo de cómo usarías las unidades basadas en contenedores es la tipografía responsiva. Las unidades basadas en viewports (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 un 15% del tamaño intercalado del contenedor, lo que significa que se agranda a medida que aumenta el tamaño intercalado (ancho) o que se reduce a medida que lo hace. Para hacer esto aún más, usa la función clamp() para otorgar a tu tipografía un límite de tamaño mínimo y máximo, 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 punto.

Esta demostración va más allá y actualiza las tarjetas más amplias 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 se sientan cómodos al incorporarlas a sus proyectos y que sepan que la compatibilidad con navegadores es una parte importante de ello. Debido a esto, estuvimos trabajando para realizar mejoras a Container Query Polyfill. 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 ResizeObserver con MutationObserver para admitir la sintaxis completa de consulta @container que actualmente está disponible 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 la consulta del contenedor

Para usar el polyfill, agrega esta 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>

También te recomendamos que uses un servicio para entregar condicionalmente el polyfill en función de User-Agent o alojarlo por cuenta propia en tu propio origen.

Para brindar la mejor experiencia del usuario, te recomendamos que inicialmente solo uses el polyfill para el contenido de la mitad inferior de la página y que las consultas @supports lo reemplacen 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 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 admite la anidación de reglas @container en consultas @supports y @media, y viceversa.
  • La CSS condicional, como @supports (container-type: inline-size), pasará después de que se cargue el polyfill.
  • Compatibilidad total con la sintaxis de CSS (ya no hay problemas para agregar comentarios en los lugares en los que sean sintácticamente válidos).
  • Modos de escritura verticales (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 propiedad y los fotogramas clave de la animación. rem y em son compatibles en las condiciones de consulta.
  • Sintaxis de consulta del contenedor expandida:
    • Sintaxis del rango (por ejemplo, (200px < width < 400px))
    • Consultas de igualdad (por ejemplo, (width = 200px))
  • Seudoelementos, como ::before y ::after.
  • Los navegadores sin :is(...) ni :where(...) son compatibles con una solución alternativa opcional.
  • Las consultas de funciones orientation y aspect-ratio
  • Filtrar correctamente las consultas según las funciones (por ejemplo, consultar height en container: inline-size no está permitido con un modo de escritura horizontal)
  • Mutación del DOM (por ejemplo, cuando se quitan elementos <style> y <link> durante el tiempo de ejecución)

Limitaciones y advertencias de Polyfill

Si usas el polyfill de la consulta del contenedor, debes tener en cuenta algunas funciones que faltan:

  • Aún no se admite el 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 de contenedores no se admiten en fotogramas clave de animaciones 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 origen cruzado ni las de estilo 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 la contención de estilo, pero está funcionando en ella.

Advertencias

  • Para evitar afectar FID y CLS, el polyfill no garantiza cuándo se producirá el primer diseño, incluso si se carga de forma síncrona, con la excepción de 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 el tamaño del bloque de un container-type: inline-size probablemente cambiará después de evaluar una consulta, pero ResizeObserver no tiene forma de indicarle que no nos importa los cambios de tamaño del bloque.
  • Este polyfill se prueba con pruebas de plataformas web y alcanza un 70% de aprobación, ya que algunas funciones como las API de JavaScript no tienen polyfills, por lo que la tasa de aprobación se acerca intencionalmente al 70%.
  • La solución alternativa :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