Ir al contenido

El medio de los artesanos de la web miércoles, 2 de septiembre de 2026

MailStudio
Diseño y UX

Container queries: componentes que se adaptan a su contenedor

Las container queries permiten que un componente responda al ancho de su contenedor en lugar del de la ventana. Ese cambio transforma la manera de construir interfaces realmente modulares, de la columna estrecha al ancho completo.

Les container queries : des composants qui s’adaptent à leur conteneur

Durante veinte años, adaptar las interfaces se apoyó en una sola referencia: el ancho de la ventana del navegador. Las media queries interrogan el viewport, nunca el espacio realmente disponible alrededor de un componente. Las container queries eliminan ese límite al dejar que un elemento responda al tamaño de su contenedor. Un mismo bloque puede mostrarse compacto en una barra lateral y extendido en el centro de la página, sin depender de la resolución de la pantalla.

El principio: interrogar al contenedor, no a la ventana

El mecanismo funciona en dos pasos. Un elemento padre se declara como contenedor de consulta; sus descendientes pueden condicionar su maquetación al tamaño de ese contenedor. La declaración usa la propiedad container-type, acompañada si hace falta de un nombre con container-name.

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

/* The card reacts to its container width, not the viewport */
@container card (min-width: 30rem) {
  .card {
    display: grid;
    grid-template-columns: 12rem 1fr;
    gap: 1.5rem;
  }
}

El valor inline-size pide al navegador que vigile la dimensión en línea, es decir el ancho en escritura horizontal, dejando libre la altura. Es el ajuste más habitual porque evita los efectos secundarios de confinar ambos ejes. Al igual que el posicionamiento de anclaje, las container queries retiran una capa de JavaScript antes necesaria para medir los elementos.

Las unidades de contenedor

Frente a las unidades relativas al viewport como vw y vh, las container queries introducen las suyas, calculadas sobre el tamaño del contenedor de consulta más cercano. Permiten dimensionar tipografía y espaciado en proporción al componente.

UnidadReferenciaEquivalente viewport
cqw1 % del ancho del contenedorvw
cqh1 % del alto del contenedorvh
cqi1 % del tamaño en líneavi
cqb1 % del tamaño de bloquevb
cqminel menor de los dosvmin
cqmaxel mayor de los dosvmax
.card h3 {
  /* Fluid heading, indexed on the container width */
  font-size: clamp(1rem, 4cqi, 1.75rem);
}

Un componente, dos contextos

La ventaja se aprecia en un componente reutilizado en varios lugares. La misma tarjeta de producto, colocada en una cuadrícula de tres columnas o en una franja a ancho completo, adopta dos maquetaciones sin una sola media query global. El marcado permanece idéntico; solo decide el ancho del contenedor.

<div class="card-container">
  <article class="card">
    <img src="/product.jpg" alt="" />
    <div class="body">
      <h3>Product name</h3>
      <p>Short description.</p>
    </div>
  </article>
</div>
viewportcontainer@container (min-width)
El componente reacciona al ancho de su contenedor, no al del viewport.

Media queries y container queries: complementarias

Las container queries no sustituyen a las media queries, las complementan. La estructura general de la página, sus márgenes de maquetación y sus grandes puntos de ruptura siguen gobernados por el viewport, porque dependen realmente del tamaño de la pantalla y de la orientación del dispositivo. Las container queries toman el relevo por dentro, en el nivel de los componentes reutilizables, donde el ancho disponible varía de un lugar a otro. Los dos mecanismos conviven en la misma hoja de estilos sin estorbarse: corresponde al autor trazar la frontera, reservando el viewport para la maquetación de conjunto y el contenedor para el comportamiento de las piezas de interfaz.

Nombrar y anidar los contenedores

La propiedad abreviada container reúne el tipo y el nombre en una sola declaración. Nombrar los contenedores se vuelve enseguida imprescindible cuando se anidan: una consulta sin nombre apunta al contenedor ancestro más cercano, que no siempre es el esperado. Con un nombre explícito, la consulta alcanza sin ambigüedad el nivel correcto, incluso a través de varios contenedores anidados. Esta disciplina de nombres refleja la de un sistema de componentes: cada zona importante de la página, barra lateral, contenido principal o pie de tarjeta, gana con un nombre estable reutilizado por los componentes que aloja.

/* Shorthand: type and name in one declaration */
.sidebar { container: rail / inline-size; }
.main    { container: content / inline-size; }

/* The query targets the nearest named container */
@container rail (max-width: 20rem) {
  .widget { font-size: 0.875rem; }
}

Despliegue progresivo

La funcionalidad está disponible en las versiones recientes de los principales navegadores, pero un sitio de gran audiencia siempre conserva una parte de visitantes en versiones antiguas. La mejora progresiva responde a este caso: la regla @supports solo activa la maquetación condicional donde container-type se reconoce, y deja en el resto una presentación de reserva perfectamente legible. El componente sigue funcionando en todas partes, simplemente enriquecido donde el navegador lo permite. Este enfoque evita la trampa clásica del todo o nada, donde una función reciente rompe la presentación en configuraciones más antiguas.

/* Progressive enhancement: only opt in when supported */
@supports (container-type: inline-size) {
  .card-container { container-type: inline-size; }
}

Tipografía y contenido que refluye

Más allá de la disposición, las container queries afinan la tipografía. Combinadas con las unidades cq* y la función clamp(), producen tamaños de texto que siguen el ancho del componente sin saltos bruscos. La comodidad de lectura se preserva cuando un mismo bloque pasa de una columna estrecha al ancho completo. Una advertencia: indexar un tamaño de fuente solo en el contenedor puede perjudicar la accesibilidad si la escala ignora las preferencias del usuario. La buena práctica consiste en acotar los valores con clamp() y conservar una base en unidades relativas, para que el zoom y los ajustes del sistema se sigan respetando.

Lo que las container queries no hacen

Un elemento no puede interrogarse a sí mismo: la consulta apunta siempre a un contenedor ancestro, nunca al elemento que declara container-type. El confinamiento también tiene un coste de renderizado, mejor reservado a los componentes que se benefician de él y no a la raíz del documento. Por último, las style queries amplían la idea a las propiedades personalizadas del contenedor, útiles junto a los design tokens.

/* Style query: react to a custom property on the container */
@container style(--density: compact) {
  .card { padding: 0.5rem; }
}

Un componente deja de ser responsive a escala de la página para serlo a escala de su ubicación.

Atención: declarar container-type: size confina ambos ejes y exige una altura explícita, o el contenido puede desaparecer. En la gran mayoría de los casos, inline-size es la opción correcta.

Lo que hay que recordar

Las container queries trasladan la lógica responsive del documento al componente. Junto con las unidades cq* y, pronto en todas partes, las style queries, hacen que las bibliotecas de interfaz sean realmente portables de un contexto a otro. Completan una familia de funciones CSS modernas junto a las View Transitions, que reducen otro tanto la dependencia de JavaScript.

Durante mucho tiempo dupliqué componentes para gestionar sus variantes según la ubicación. Desde que me apoyo en las container queries, mantengo un único componente y dejo que se adapte donde se coloca: mi CSS ha adelgazado y mis revisiones de código también. Es uno de los pocos cambios que simplifica a la vez el código y la arquitectura. — Simon Janvier

Para profundizar

Documentación de referencia: Container queries en MDN.

Compartir LinkedIn Bluesky Hacker News E-mail

Leer también