@container y :has(): dos APIs responsivas nuevas y potentes que llegan a Chromium 105

Las consultas de contenedores y :has() son una combinación perfecta para el diseño responsivo. Por suerte, ambas funciones se lanzarán juntas en Chromium 105. Se trata de un gran lanzamiento con dos funciones muy solicitadas para las interfaces responsivas.

Consultas de contenedores: un resumen rápido

Las consultas de contenedores permiten a los desarrolladores consultar un selector superior para obtener información sobre su tamaño y estilo, lo que posibilita que un elemento secundario posea la lógica de diseño responsivo, sin importar dónde se encuentre en la página web.

En lugar de depender del viewport para la entrada de diseño, como el espacio disponible, los desarrolladores ahora también pueden consultar el tamaño de los elementos de la página. Esta función significa que un componente es propietario de su lógica de diseño responsivo. Esto hace que el componente sea mucho más resistente, ya que la lógica de diseño está adjunta a él, sin importar dónde aparezca en la página.

Usa consultas de contenedores

Para compilar con consultas de contenedor, primero debes establecer la contención en un elemento superior. Para ello, establece un container-type en el contenedor superior. Puedes tener una tarjeta con una imagen y un poco de contenido de texto que se vea de la siguiente manera:

Tarjeta única de dos columnas.

Para crear una consulta de contenedor, establece container-type en el contenedor de tarjetas:

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

Si estableces container-type en inline-size, se consulta el tamaño de la dirección intercalada del elemento superior. En idiomas latinos, como el inglés, este sería el ancho de la tarjeta, ya que el texto fluye intercalado de izquierda a derecha.

Ahora, podemos usar ese contenedor para aplicar estilos a cualquiera de sus elementos secundarios con @container:

.card {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

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

El selector superior :has()

La pseudoclase :has() de CSS permite que los desarrolladores verifiquen si un elemento superior contiene elementos secundarios con parámetros específicos.

Por ejemplo, p:has(span) indica un selector de párrafo (p), que tiene un span dentro. Puedes usar esto para aplicar un estilo al párrafo superior o a cualquier elemento dentro de él. Un ejemplo útil es figure:has(figcaption) para aplicar diseño a un elemento figure que contiene un título. Puedes ver mucho más sobre :has() en este artículo de Jhey Tompkins.

Consultas de contenedores y :has()

Puedes combinar los poderes de selección superiores de :has() con los poderes de consulta superiores de las consultas de contenedor para crear estilos intrínsecos realmente dinámicos.

Ampliemos el primer ejemplo con la tarjeta del cohete. ¿Qué sucedería si tuvieras una tarjeta sin imagen? Tal vez quieras aumentar el tamaño del título y ajustar el diseño de cuadrícula a una sola columna para que se vea más intencional sin la imagen.

Texto más grande en la tarjeta sin la imagen, que se muestra en una columna.

En este ejemplo, la tarjeta con una imagen tiene una plantilla de cuadrícula de dos columnas, mientras que la tarjeta sin la imagen tiene un diseño de una sola columna. Además, la tarjeta sin la imagen tiene un encabezado más grande. Para escribir esto con :has(), usa el siguiente CSS.

.card:has(.visual) {
  grid-template-columns: 1fr 1fr;
}

Buscas un elemento con una clase de visual para aplicar el estilo de dos columnas anterior. Otra función interesante de CSS es :not(). Esto forma parte de la misma especificación que :has(), pero existe desde hace mucho tiempo y tiene una mejor compatibilidad con navegadores. Incluso puedes combinar :has() y :not() de la siguiente manera:

.card:not(:has(.visual)) h1 {
  font-size: 4rem;
}

En el código anterior, escribes un selector que diseña una h1 dentro de una tarjeta que no contiene una clase visual. Así es como puedes ajustar muy claramente el tamaño de la fuente.

Revisión general

En la demostración anterior, se muestra una combinación de :has(), :not() y @container, pero las consultas de contenedores realmente se destacan cuando puedes ver que el mismo elemento se usa en varios lugares. Agreguemos un toque de estilo y mostremos estas tarjetas en una cuadrícula una junto a la otra.

Ahora realmente puedes ver el poder del CSS moderno. Podemos escribir estilos claros con estilos segmentados que compilan lógica sobre lógica y crean componentes realmente sólidos. Con estas dos funciones potentes que llegan a Chromium 105 y que están ganando impulso en la compatibilidad multinavegador, es un momento emocionante para ser desarrollador de IU.