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

Las consultas de contenedores y :has() son una coincidencia en el cielo receptivo. Afortunadamente, ambas funciones están llegando juntas en Chromium 105. Se trata de un gran lanzamiento con dos funciones muy solicitadas para interfaces responsivas.

Container Queries: un resumen rápido

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

En lugar de depender del viewport para aplicar estilo a la entrada, como el espacio disponible, los desarrolladores ahora también pueden consultar el tamaño de los elementos in-page. Esta capacidad significa que un componente posee su lógica de estilo responsiva. Esto hace que el componente sea mucho más resistente, ya que se le adjunta la lógica de diseño, sin importar en qué parte de la página aparezca.

Usa consultas de contenedores

Para compilar con consultas de contenedores, primero debes establecer la contención en un elemento superior. Para ello, configura un container-type en el contenedor superior. Puedes tener una tarjeta con una imagen y contenido de texto similar al siguiente:

Tarjeta de dos columnas

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

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

Cuando se configura container-type como 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;
  }
}

Selector principal de :has()

La seudoclase :has() de CSS permite a los desarrolladores verificar 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 estilo al párrafo superior en sí, o para aplicarle estilo. Un ejemplo útil es figure:has(figcaption) para aplicar estilo a un elemento figure que contenga una leyenda. Puedes obtener más información sobre :has() en este artículo de Jhey Tompkins.

Consultas de contenedores y :has()

Puedes combinar las potencias de selección superiores de :has() con las potencias de consulta superiores de las consultas de contenedores para crear algunos estilos intrínsecos muy dinámicos.

Expandamos el primer ejemplo con la tarjeta de cohete. ¿Qué pasa si tiene una tarjeta sin una imagen? Quizás 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.

Es el texto más grande de la tarjeta sin la imagen y 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 visual para aplicar el estilo de dos columnas anterior. Otra función útil de CSS es :not(). Esto forma parte de las mismas especificaciones que :has(), pero existe desde hace mucho más 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 un 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 se usa el mismo elemento en varios lugares. Agreguemos un toque de estilo y mostremos estas tarjetas en una cuadrícula una al lado de la otra.

Ahora puedes apreciar de verdad el poder del CSS moderno. Podemos escribir estilos claros con estilos específicos que compilen lógica sobre la base de la lógica y creen componentes realmente sólidos. Con estas dos potentes funciones que llegan a Chromium 105 y están ganando impulso en la compatibilidad con varios navegadores, es un momento emocionante para ser desarrollador de IU.