Desarrollo Web 5-8 minutos

Container queries y :has(): el CSS moderno que ya puedes usar en producción

Diego Cortés
Diego Cortés
Full Stack Developer & SEO Specialist
Compartir:
Container queries y :has(): el CSS moderno que ya puedes usar en producción

Las container queries son Baseline desde febrero de 2023 y el selector :has() desde diciembre de 2023: en 2026 usarlos en producción es lo normal. Aprende a crear componentes que responden a su propio contenedor con estas dos features del CSS moderno.

De los media queries a las container queries

Durante años, los media queries fueron la única herramienta para hacer CSS responsive. Funcionan, pero tienen una limitación estructural: solo conocen el tamaño del viewport, no el del componente que estás estilizando.

El problema del componente que no conoce su propio ancho

Imagina una card que se usa tanto en la barra lateral como en el contenido principal. En un caso tiene 300 píxeles de ancho y en el otro 800, pero los media queries no pueden distinguir entre las dos situaciones: ambas ocurren en el mismo viewport. El resultado son trucos como clases condicionales desde JavaScript, calculadoras de anchos o media queries anidados que nadie quiere mantener. Las container queries resuelven exactamente ese problema: el componente reacciona al tamaño de su propio contenedor.

Qué es un containment context

Para que un componente pueda consultar el tamaño de su contenedor, ese contenedor debe registrarse como tal. Ese registro crea lo que se llama un containment context: un elemento que actúa como referencia de tamaño para sus descendientes. Solo los elementos dentro de ese contexto pueden usar container queries contra él, y el navegador sabe que los cambios de tamaño internos no deben propagarse más allá, lo que además mejora el rendimiento del layout.

Container queries en la práctica

La API es sencilla: declaras un contenedor con una propiedad CSS y luego escribes reglas condicionales con @container. Veamos las piezas clave.

container-type y container-name

Para registrar un contenedor se usa la propiedad container, que combina container-type y container-name. El valor más habitual es container-type: inline-size, que crea un contexto basado en el ancho del contenedor. Con container-name puedes ponerle un nombre y consultarlo de forma explícita:

/* CSS */
.card-wrapper { container: card / inline-size; }

Después, cualquier descendiente puede reaccionar al ancho de ese contenedor:

/* CSS */
@container card (min-width: 600px) {
  .card__media { display: block; }
}

Las unidades de contenedor: cqw, cqh, cqi y cqb

Además de las consultas, el CSS moderno ofrece unidades relativas al contenedor, equivalentes a las unidades de viewport pero con otro contexto: cqw es el 1 por ciento del ancho del contenedor, cqh el 1 por ciento de su alto, cqi el 1 por ciento del tamaño inline y cqb el 1 por ciento del tamaño block. También existen cqmin y cqmax, que toman el menor o el mayor de cqi y cqb. Son ideales para tipografía y espaciado que deben escalar con el contenedor.

Style queries: @container style()

Las container queries también pueden consultar propiedades del contenedor, no solo su tamaño. Con @container style(...) aplicas estilos según el valor de una propiedad CSS del contenedor, lo que abre la puerta a variantes de tema o de estado sin tocar clases. Es una característica más reciente, pero ya con casos de uso reales en producción.

:has(), el selector que mira hacia dentro

El selector :has() es el complemento perfecto de las container queries. Mientras estas responden al tamaño del contenedor, :has() permite estilizar un elemento según lo que contiene. Se le llama el selector padre, porque por fin un padre puede reaccionar a sus hijos.

Casos reales: cards con imagen y formularios con error

Un caso clásico: una card que ajusta su espaciado cuando incluye una imagen. Con :has() no necesitas una clase extra en el HTML:

/* CSS */
.card:has(.card__media) { padding: 0; }

Otro ejemplo muy útil: un grupo de formulario que cambia el borde cuando el campo interno es inválido:

/* CSS */
.field-group:has(input:invalid) { border-color: #dc2626; }

Rendimiento y buenas prácticas

Los motores modernos resuelven :has() de forma eficiente, pero conviene evitar selectores excesivamente complejos que se evalúen sobre muchos nodos a la vez. En la práctica, usarlo con moderación y con selectores simples funciona bien incluso en listas largas. La regla de oro: si puedes resolverlo con una clase o un atributo, hazlo; :has() brilla cuando el HTML no debería cambiar solo por estilos.

Soporte en 2026: de Baseline a producción

La pregunta que todos se hacen es si pueden usar estas features ya. La respuesta corta es sí, y los datos de soporte lo confirman.

La línea de tiempo de Baseline

Container queries entraron en Baseline como recién disponibles en febrero de 2023 y :has() hizo lo propio en diciembre de 2023. Desde entonces, Chrome, Firefox, Safari y Edge las soportan de forma estable. El proyecto Baseline, impulsado por el equipo de web.dev, clasifica las features de la plataforma web según su compatibilidad, y ambas llevan años en la categoría de uso seguro. Los polyfills solo tienen sentido si una parte significativa de tu audiencia usa navegadores muy antiguos, algo cada vez más excepcional en 2026.

Qué más puedes usar hoy: CSS nesting y cascade layers

Estas dos features no están solas: el CSS moderno de 2026 incluye también el anidamiento nativo (CSS nesting), las cascade layers para organizar la especificidad, la View Transitions API y la Popover API, entre otras. Juntas cambian por completo la forma de estructurar una hoja de estilos: menos preprocesadores, menos clases utilitarias inventadas y más CSS declarativo que el navegador entiende directamente.

Ejemplo completo: una card que se adapta sola

Cerremos con un ejemplo que combina todo. Una card que se muestra en horizontal cuando su contenedor es ancho y en vertical cuando es estrecho, y que además ajusta su padding si tiene imagen:

/* CSS */
.card { container: card / inline-size; }

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

.card:has(.card__media) { padding: 0; }
.card__title { font-size: clamp(1rem, 4cqi, 1.5rem); }

El mismo componente, sin una sola clase condicional, cambia su layout según el espacio que realmente tiene y escala su tipografía con las unidades de contenedor. Colócalo en la barra lateral o en el contenido principal y se adaptará solo.

Conclusión

Las container queries y :has() son el corazón del CSS moderno de 2026: componentes que responden a su propio contexto y selectores que miran hacia dentro, ambos con soporte estable en todos los navegadores principales. No necesitas reescribir toda tu hoja de estilos: empieza por un componente reutilizable, aplica un containment context y deja que :has() elimine clases innecesarias. El resultado es CSS más limpio, más mantenible y más predecible. Sigue leyendo el blog para más artículos de desarrollo web.

Categorías