1

CSS Container Queries na Prática: Componentes Responsivos Sem JavaScript

O problema que media queries nunca resolveram

Um card de produto precisa funcionar em três contextos: sidebar de 280px, grid de duas colunas e hero de largura total. Com media queries, você escreve breakpoints baseados na viewport. O card não sabe se está numa sidebar ou num grid: ele só sabe a largura da janela do navegador.

O resultado é previsível: você acaba criando variantes com classes CSS (.card--small, .card--large) ou, pior, usando ResizeObserver em JavaScript para medir o container pai e aplicar classes dinamicamente. Container queries resolvem isso na camada certa: o componente reage ao espaço que o container pai oferece, não à viewport.

Como container queries funcionam por baixo

O mecanismo depende de dois conceitos: containment context e container query.

Primeiro, você declara um elemento como container de consulta. Isso instrui o navegador a rastrear as dimensões desse elemento para que filhos possam consultá-las. Segundo, você escreve regras @container que funcionam como media queries, mas consultam o container ancestral mais próximo.

/* Declara o wrapper como container nomeado */
.product-list {
  container-type: inline-size;
  container-name: product-list;
}

/* O card filho consulta o container, não a viewport */
@container product-list (min-width: 600px) {
  .product-card {
    display: grid;
    grid-template-columns: 200px 1fr;
    gap: 1.5rem;
  }
}

container-type: inline-size ativa containment apenas no eixo inline (horizontal em LTR). Existe size para ambos os eixos, mas raramente você precisa dele: containment em ambos os eixos exige que o elemento tenha altura explícita, o que quebra layouts com conteúdo dinâmico.

Container query vs. media query: quando usar cada uma

CritérioMedia queryContainer query
Referência de medidaViewport do navegadorElemento container pai
Caso de uso principalLayouts de página (header, grid global, nav)Componentes reutilizáveis (cards, widgets, forms)
ComposiçãoNão compõe: mesmo breakpoint para todos os contextosCompõe: cada instância reage ao próprio container
Suporte (2024+)Universal96%+ dos navegadores (baseline desde dezembro 2023)
Eixo verticalFunciona com min-heightRequer container-type: size e altura explícita
PerformanceSem custo extra de layoutCusto marginal de containment (imperceptível em cenários reais)

A regra prática: use media queries para o layout da página e container queries para componentes que vivem dentro desse layout. As duas coexistem sem conflito.

Card de produto responsivo ao container

Este é o caso de uso mais comum. O card empilha imagem sobre texto quando o container é estreito e muda para layout horizontal quando há espaço.

/* container.css */
.card-container {
  container-type: inline-size;
  container-name: card-wrapper;
}

.product-card {
  display: flex;
  flex-direction: column;
  border: 1px solid hsl(220 10% 90%);
  border-radius: 0.5rem;
  overflow: hidden;
}

.product-card__image {
  aspect-ratio: 16 / 9;
  object-fit: cover;
  width: 100%;
}

.product-card__body {
  padding: 1rem;
}

.product-card__title {
  font-size: 1rem;
  margin: 0 0 0.5rem;
}

/* Quando o container tem pelo menos 500px, layout horizontal */
@container card-wrapper (min-width: 500px) {
  .product-card {
    flex-direction: row;
  }

  .product-card__image {
    /* Limita a imagem a 40% do espaço horizontal para
       manter proporção legível no texto ao lado */
    width: 40%;
    aspect-ratio: 1 / 1;
  }

  .product-card__title {
    font-size: 1.25rem;
  }
}

/* Container largo: card vira destaque com tipografia maior */
@container card-wrapper (min-width: 800px) {
  .product-card__title {
    font-size: 1.5rem;
  }

  .product-card__body {
    padding: 1.5rem 2rem;
  }
}
<!-- O mesmo card funciona em qualquer contexto sem classes extras -->
<div class="card-container" style="width: 300px;">
  <article

---

Leia o artigo completo em [https://www.vivodecodigo.com.br/react/css-container-queries-componentes-responsivos-sem-javascript](https://www.vivodecodigo.com.br/react/css-container-queries-componentes-responsivos-sem-javascript)
Carregando publicação patrocinada...