@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 la respuesta. Por suerte, ambas funciones se lanzarán juntas en Chromium 105. Esta es una gran versión con dos funciones muy solicitadas para interfaces responsivas.

Consultas de contenedores: un resumen rápido

Las consultas de contenedor permiten a los desarrolladores consultar un selector superior para obtener información sobre su tamaño y diseño, lo que permite que un elemento secundario tenga su propia lógica de diseño responsivo, sin importar dónde se encuentre en una 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é sucede si tienes 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(). Forma parte de la misma especificación que :has(), pero lleva mucho más tiempo disponible y tiene una mejor compatibilidad con los 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 aplica diseño a un h1 dentro de una tarjeta que no contiene una clase visual. De esta manera, puedes ajustar el tamaño de la fuente con mucha claridad.

Revisión general

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

Ahora puedes ver realmente 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.