Fundamentos de las container queries
El diseño responsive tradicional con Tailwind CSS se basa en el ancho del viewport del navegador. Los prefijos sm:, md:, lg: aplican estilos cuando la ventana del navegador alcanza determinado tamaño. Sin embargo, esto presenta un problema frecuente: un componente que se reutiliza en distintas zonas de la página (barra lateral, contenido principal, modal) necesita adaptarse al espacio disponible de su contenedor padre, no al tamaño de la ventana completa.

Las container queries resuelven esta limitación permitiendo que un componente responda al tamaño de su contenedor más cercano. Tailwind CSS 4 incorpora soporte nativo para container queries con una sintaxis limpia basada en variantes.
Para activar las container queries en un elemento, se utiliza la clase @container en el elemento padre. Esta clase establece el contexto de contenedor que los elementos hijos pueden consultar.
<div class="@container">
<div class="flex flex-col @md:flex-row gap-4">
<img src="producto.jpg" alt="Producto" class="w-full @md:w-48 rounded">
<div>
<h3 class="text-lg font-semibold">Nombre del producto</h3>
<p class="text-gray-600">Descripción del producto</p>
</div>
</div>
</div>
En este ejemplo, el contenedor padre tiene la clase @container. Los elementos hijos utilizan la variante @md: para cambiar de disposición vertical a horizontal cuando el contenedor (no el viewport) alcanza el tamaño md.
La diferencia clave entre
md:flex-rowy@md:flex-rowes que el primero responde al ancho de la ventana del navegador, mientras que el segundo responde al ancho del contenedor padre marcado con@container.
Variantes de container query
Tailwind CSS 4 proporciona variantes de container query que siguen los mismos nombres que los breakpoints responsive, pero con el prefijo @. Los tamaños predeterminados coinciden con los breakpoints del tema:
@smse activa cuando el contenedor alcanza40rem(640px)@mdse activa cuando el contenedor alcanza48rem(768px)@lgse activa cuando el contenedor alcanza64rem(1024px)@xlse activa cuando el contenedor alcanza80rem(1280px)@2xlse activa cuando el contenedor alcanza96rem(1536px)
Estas variantes se combinan con cualquier clase de utilidad de Tailwind CSS exactamente igual que las variantes responsive del viewport.
<div class="@container bg-white p-6 rounded-lg shadow">
<div class="grid grid-cols-1 @sm:grid-cols-2 @lg:grid-cols-3 gap-4">
<div class="bg-gray-100 p-4 rounded">Elemento 1</div>
<div class="bg-gray-100 p-4 rounded">Elemento 2</div>
<div class="bg-gray-100 p-4 rounded">Elemento 3</div>
</div>
</div>
Este grid comienza con una sola columna y pasa a dos columnas cuando el contenedor mide al menos 40rem, y a tres columnas cuando alcanza 64rem.
Valores arbitrarios en container queries
Además de los breakpoints predefinidos, es posible utilizar valores arbitrarios directamente en la variante. Esto resulta útil cuando se necesita un punto de corte específico que no coincide con los breakpoints del tema.
<div class="@container">
<p class="text-sm @[400px]:text-base @[600px]:text-lg">
Este texto ajusta su tamaño según el ancho del contenedor.
</p>
</div>
La sintaxis @[400px] crea una container query que se activa exactamente cuando el contenedor alcanza 400px de ancho.
Contenedores con nombre
Cuando existen varios contenedores anidados, las container queries responden al contenedor más cercano marcado con @container. Para apuntar a un contenedor específico, se utiliza la sintaxis de contenedores con nombre.
El nombre se asigna añadiendo una barra y el identificador a la clase @container:
<div class="@container/sidebar">
<div class="p-4">
<div class="@container/card">
<div class="flex flex-col @sm/card:flex-row @lg/sidebar:gap-8 gap-4">
<img src="avatar.jpg" alt="Avatar" class="w-16 h-16 rounded-full">
<div>
<h4 class="font-bold">Nombre de usuario</h4>
<p class="text-sm text-gray-500">Descripción breve</p>
</div>
</div>
</div>
</div>
</div>
En este ejemplo se definen dos contenedores con nombre: sidebar y card. La variante @sm/card: consulta el ancho del contenedor llamado card, mientras que @lg/sidebar: consulta el ancho del contenedor llamado sidebar.
Los contenedores con nombre permiten que un componente profundamente anidado responda al tamaño de un ancestro específico, sin importar cuántos contenedores intermedios existan.
Estructura de la sintaxis
La forma general de las variantes de container query con nombre es:
@{breakpoint}/{nombre}:{utilidad}para un breakpoint predefinido@[{valor}]/{nombre}:{utilidad}para un valor arbitrario
<div class="@container/main">
<article class="@container/article">
<h2 class="text-xl @md/article:text-2xl @lg/main:text-3xl">
Título del artículo
</h2>
<p class="@sm/article:columns-2 @md/main:columns-3">
Contenido del artículo que se distribuye en columnas
según el tamaño de los distintos contenedores.
</p>
</article>
</div>
Rangos con @min y @max
Tailwind CSS 4 incluye variantes de rango para container queries que permiten definir condiciones de tamaño mínimo y máximo. Estas variantes funcionan de forma similar a min-width y max-width en media queries tradicionales.
La variante @min- aplica estilos cuando el contenedor tiene al menos el tamaño indicado, y @max- cuando el contenedor tiene como máximo ese tamaño.
<div class="@container">
<div class="@min-sm:p-6 @max-md:bg-blue-50 @min-lg:bg-green-50 p-3">
<p class="@max-sm:text-sm @min-md:text-lg">
Texto adaptativo con rangos de container query.
</p>
</div>
</div>
La combinación de @min- y @max- permite crear rangos exclusivos donde los estilos solo se aplican dentro de un intervalo de tamaño determinado.
<div class="@container">
<!-- Visible solo cuando el contenedor mide entre sm y lg -->
<p class="hidden @min-sm:block @min-lg:hidden">
Contenido visible solo en tamaños intermedios del contenedor.
</p>
</div>
Caso práctico: tarjeta adaptable al contenedor
Un caso de uso habitual es una tarjeta de producto que se muestra en distintos contextos de la aplicación: una cuadrícula amplia, una barra lateral estrecha o un modal de tamaño medio. Con container queries, un único componente se adapta a cada situación.
<!-- Tarjeta en la zona principal -->
<div class="@container w-full">
<div class="bg-white rounded-xl shadow-md overflow-hidden
flex flex-col @sm:flex-row">
<img src="producto.jpg" alt="Producto"
class="w-full @sm:w-40 @md:w-56 h-48 @sm:h-auto object-cover">
<div class="p-4 @md:p-6 flex flex-col justify-between">
<div>
<span class="text-xs @md:text-sm font-medium text-blue-600 uppercase">
Categoría
</span>
<h3 class="text-lg @md:text-xl font-bold mt-1">
Nombre del producto
</h3>
<p class="text-gray-600 mt-2 hidden @sm:block">
Descripción detallada que solo aparece cuando
el contenedor tiene suficiente espacio.
</p>
</div>
<div class="flex items-center justify-between mt-4">
<span class="text-xl font-bold text-gray-900">29,99 EUR</span>
<button class="bg-blue-600 text-white px-4 py-2 rounded-lg
text-sm @md:text-base @md:px-6">
Comprar
</button>
</div>
</div>
</div>
</div>
Esta tarjeta se muestra en disposición vertical cuando el contenedor es estrecho. Al alcanzar el breakpoint @sm, cambia a disposición horizontal con la imagen a la izquierda. En @md, la imagen crece, el padding aumenta y el texto del botón se hace más grande.
Caso práctico: barra lateral con contenido adaptable
Otro patrón frecuente es una barra lateral colapsable donde los componentes internos se reorganizan según el ancho disponible.
<aside class="@container w-64 lg:w-80 bg-gray-50 border-r min-h-screen">
<!-- Perfil de usuario -->
<div class="flex items-center gap-3 @[200px]:flex-row flex-col
text-center @[200px]:text-left p-4">
<img src="avatar.jpg" alt="Avatar"
class="w-12 h-12 rounded-full">
<div>
<p class="font-semibold text-sm">Ana García</p>
<p class="text-xs text-gray-500 hidden @[200px]:block">
ana@ejemplo.com
</p>
</div>
</div>
<!-- Menú de navegación -->
<nav class="mt-4">
<a href="#" class="flex items-center gap-3 px-4 py-2
hover:bg-gray-200 rounded-lg mx-2">
<svg class="w-5 h-5 shrink-0" fill="currentColor" viewBox="0 0 20 20">
<!-- Icono -->
</svg>
<span class="hidden @[180px]:inline text-sm">Inicio</span>
</a>
<a href="#" class="flex items-center gap-3 px-4 py-2
hover:bg-gray-200 rounded-lg mx-2">
<svg class="w-5 h-5 shrink-0" fill="currentColor" viewBox="0 0 20 20">
<!-- Icono -->
</svg>
<span class="hidden @[180px]:inline text-sm">Configuración</span>
</a>
</nav>
</aside>
En este ejemplo, las etiquetas de texto del menú se ocultan cuando la barra lateral es demasiado estrecha (por debajo de 180px), mostrando únicamente los iconos. El perfil de usuario pasa de disposición vertical a horizontal según el espacio disponible, utilizando un valor arbitrario de 200px.
Comparativa entre variantes de viewport y container queries
Para decidir qué enfoque utilizar, conviene analizar el contexto de uso del componente.
<!-- Responsive al VIEWPORT: ideal para layouts de página completa -->
<main class="grid grid-cols-1 md:grid-cols-3 gap-6 p-6">
<!-- ... -->
</main>
<!-- Responsive al CONTENEDOR: ideal para componentes reutilizables -->
<div class="@container">
<div class="grid grid-cols-1 @md:grid-cols-3 gap-6 p-6">
<!-- ... -->
</div>
</div>
Las variantes de viewport (sm:, md:, lg:) resultan apropiadas para definir la estructura general de la página: cuántas columnas tiene el layout principal, si la barra lateral se muestra o se oculta, y cómo se distribuyen las secciones principales.
Las variantes de container query (@sm:, @md:, @lg:) resultan apropiadas para componentes que se reutilizan en distintos contextos y necesitan adaptarse al espacio que realmente tienen disponible, independientemente del tamaño de la ventana del navegador.
Alan Sastre
Ingeniero de Software y formador, CEO en CertiDevs
Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Tailwind CSS es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.
Más tutoriales de Tailwind CSS
Explora más contenido relacionado con Tailwind CSS y continúa aprendiendo con nuestros tutoriales gratuitos.
Aprendizajes de esta lección
- Comprender la diferencia entre variantes responsive de viewport y container queries
- Aplicar la clase @container y las variantes @sm, @md, @lg para diseño adaptable al contenedor
- Utilizar contenedores con nombre para apuntar a ancestros específicos
- Emplear valores arbitrarios y rangos con @min y @max en container queries
Cursos que incluyen esta lección
Esta lección forma parte de los siguientes cursos estructurados con rutas de aprendizaje