Design responsivo na prática: guia de CSS moderno (2026)

Aprenda design responsivo com mobile-first, media queries, container queries, clamp(), unidades fluidas e imagens responsivas, com exemplos de CSS prontos.

Design responsivo é fazer uma única página funcionar bem em qualquer tela, e em 2026 isso se resolve quase todo com CSS nativo: comece pelo layout do celular (mobile-first), use Grid e Flexbox, tamanhos fluidos com clamp(), media queries para mudanças de layout da página, container queries para componentes e srcset/sizes para imagens. Nada de framework obrigatório e nada de lista de "breakpoints do iPhone".

Abaixo, cada técnica com CSS que você pode copiar e adaptar.

O ponto de partida: a meta viewport

Sem essa linha, o navegador do celular finge ter uma tela de desktop e encolhe tudo. Ela vai em toda página:

<meta name="viewport" content="width=device-width, initial-scale=1">

Não use maximum-scale=1 ou user-scalable=no: impedir o zoom prejudica acessibilidade.

E um reset mínimo que evita metade dos bugs de layout:

*, *::before, *::after {
  box-sizing: border-box;
}

img, picture, video, svg {
  display: block;
  max-width: 100%;
  height: auto;
}

Mobile-first: escreva para o celular primeiro

Mobile-first significa que o CSS sem media query é o do celular, e você adiciona regras conforme a tela cresce, com min-width.

/* Base: celular, uma coluna */
.produtos {
  display: grid;
  gap: 1rem;
}

/* A partir de ~768px: duas colunas */
@media (min-width: 48rem) {
  .produtos {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* A partir de ~1024px: três colunas */
@media (min-width: 64rem) {
  .produtos {
    grid-template-columns: repeat(3, 1fr);
  }
}

Por que mobile-first é melhor:

  • O celular recebe o CSS mais simples, sem precisar desfazer regras de desktop.
  • Força você a priorizar conteúdo: em 360 px de largura não cabe enrolação.
  • Na maioria dos sites, o celular é onde está o maior volume de acessos.

Dica: use rem nos breakpoints em vez de px. Se o usuário aumentar o tamanho de fonte padrão do navegador, o layout se adapta junto.

Às vezes você nem precisa de media query

Este grid cria quantas colunas couberem, cada uma com no mínimo 16rem, sem um único breakpoint:

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(16rem, 100%), 1fr));
  gap: 1.5rem;
}

O min(16rem, 100%) evita que o card estoure a tela em celulares muito estreitos. Esse padrão resolve a maioria das listagens de cards, produtos e posts.

Media queries modernas

Além de largura, media queries detectam preferências do usuário e capacidade do aparelho.

/* Sintaxe de intervalo, suportada nos navegadores atuais */
@media (48rem <= width < 64rem) {
  .sidebar { display: none; }
}

/* Dispositivo com mouse: efeito de hover faz sentido */
@media (hover: hover) and (pointer: fine) {
  .botao:hover { background: var(--cor-destaque); }
}

/* Usuário pediu menos animação */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Tema escuro do sistema */
@media (prefers-color-scheme: dark) {
  :root {
    --fundo: #0f172a;
    --texto: #e2e8f0;
  }
}

A consulta hover é subestimada: em telas touch não existe hover de verdade, e menus que só abrem no hover viram armadilha no celular.

Container queries: componentes que se adaptam ao espaço

O problema clássico: o mesmo card aparece numa coluna larga e numa sidebar estreita. A media query só enxerga a janela, então não ajuda. A container query olha para o tamanho do elemento pai.

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

/* Card padrão: empilhado (imagem em cima, texto embaixo) */
.card {
  display: grid;
  gap: 1rem;
}

/* Quando o CONTÊINER tiver 30rem ou mais, vira horizontal */
@container card (min-width: 30rem) {
  .card {
    grid-template-columns: 12rem 1fr;
    align-items: start;
  }
}
<div class="card-wrapper">
  <article class="card">
    <img src="foto.jpg" alt="Descrição da foto" width="600" height="400">
    <div>
      <h3>Título do card</h3>
      <p>Resumo do conteúdo.</p>
    </div>
  </article>
</div>

Container queries têm suporte em todos os navegadores modernos. A regra prática: media query para o layout da página, container query para o layout do componente.

Dentro do contêiner você também pode usar unidades relativas a ele, como cqi (1% da largura do contêiner):

.card h3 {
  font-size: clamp(1.1rem, 4cqi, 1.6rem);
}

Unidades fluidas: escolha a certa

Unidade Relativa a Use para
rem Tamanho de fonte da raiz Fontes, espaçamentos, breakpoints
em Fonte do próprio elemento Padding de botões que escala com o texto
% Elemento pai Larguras dentro de um contêiner
vw / vh Viewport Elementos de tela inteira (com cuidado)
svh / lvh / dvh Viewport pequena, grande e dinâmica Alturas de tela cheia no celular
ch Largura do caractere "0" Largura máxima de texto legível
cqi / cqb Contêiner da container query Tamanhos dentro de componentes
fr Espaço livre no grid Colunas e linhas do CSS Grid

O problema do 100vh no celular

No celular, a barra de endereço aparece e some com a rolagem. 100vh costuma ignorar isso, e seu "hero de tela cheia" fica com o botão escondido atrás da barra. Use as unidades novas:

.hero {
  min-height: 100svh; /* cabe mesmo com a barra do navegador visível */
}

svh é a altura com as barras visíveis (a menor), lvh a maior, e dvh muda dinamicamente durante a rolagem. Para seções de tela cheia, svh costuma ser a escolha mais segura; dvh pode causar "pulos" de layout enquanto o usuário rola.

Texto legível

.artigo {
  max-width: 65ch;
  margin-inline: auto;
  padding-inline: 1rem;
}

Linhas entre 45 e 75 caracteres são a faixa clássica de conforto de leitura. 65ch resolve isso em uma linha.

clamp(): tipografia e espaçamento fluidos

clamp(mínimo, ideal, máximo) deixa um valor crescer com a tela, mas dentro de limites.

h1 {
  font-size: clamp(1.75rem, 1.2rem + 2.5vw, 3rem);
}

.secao {
  padding-block: clamp(2rem, 5vw, 6rem);
}

O título fica com no mínimo 1.75rem no celular, no máximo 3rem em telas grandes, e cresce suavemente no meio. Sem breakpoint.

Atenção: nunca use só vw no valor ideal de fonte (clamp(1rem, 4vw, 2rem)). Unidades de viewport puras não respondem ao zoom do usuário, o que é um problema de acessibilidade. Somar rem + vw, como no exemplo acima, resolve.

Funções irmãs úteis: min() e max(). Por exemplo, width: min(100% - 2rem, 70rem) cria um contêiner centralizado com margem lateral no celular e largura máxima no desktop:

.container {
  width: min(100% - 2rem, 70rem);
  margin-inline: auto;
}

Imagens responsivas

Imagem é quase sempre o maior peso da página. Mandar uma foto de 2.400 px para um celular de 390 px é desperdício de dados e de tempo.

Mesma imagem, tamanhos diferentes: srcset + sizes

<img
  src="cafe-800.jpg"
  srcset="cafe-400.jpg 400w, cafe-800.jpg 800w, cafe-1600.jpg 1600w"
  sizes="(min-width: 64rem) 33vw, (min-width: 48rem) 50vw, 100vw"
  width="1600" height="1067"
  alt="Xícara de café sobre mesa de madeira"
  loading="lazy"
  decoding="async">
  • srcset lista os arquivos e a largura real de cada um (w).
  • sizes diz ao navegador qual largura a imagem vai ocupar na tela. Aqui: um terço da tela no desktop, metade no tablet, tela toda no celular.
  • O navegador escolhe o arquivo ideal considerando também a densidade de pixels.
  • width e height evitam que o layout "pule" quando a imagem carrega (o CSS com height: auto mantém a proporção).
  • loading="lazy" adia imagens fora da tela. Não use na imagem principal do topo da página: nela, prefira fetchpriority="high".

Formatos modernos e recorte diferente: <picture>

<picture>
  <source media="(min-width: 48rem)" srcset="banner-largo.avif" type="image/avif">
  <source media="(min-width: 48rem)" srcset="banner-largo.webp" type="image/webp">
  <source srcset="banner-quadrado.avif" type="image/avif">
  <source srcset="banner-quadrado.webp" type="image/webp">
  <img src="banner-quadrado.jpg" alt="Promoção de lançamento" width="800" height="800">
</picture>

Isso entrega um recorte quadrado no celular e um banner largo no desktop (o que se chama de art direction), em AVIF ou WebP quando suportado, com JPG de fallback.

Proporção fixa com aspect-ratio

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

Checklist antes de publicar

Item Como testar
Sem rolagem horizontal em 320 px DevTools, modo responsivo
Áreas de toque com ~44 px ou mais Toque com o dedo, não com o mouse
Texto legível sem zoom (16px ou mais no corpo) Celular real
Zoom de até 200% sem quebrar Ctrl/Cmd + no navegador
Imagens no tamanho certo Aba Network do DevTools
Funciona com tela na horizontal Gire o celular
Formulários com type correto (email, tel) O teclado certo abre no celular?
Core Web Vitals aceitáveis Lighthouse e PageSpeed Insights

O modo responsivo do DevTools ajuda muito, mas teste também em um celular de verdade, de preferência um Android intermediário. É lá que aparecem os problemas de desempenho que o seu notebook esconde.

Próximos passos

Design responsivo é a base de tudo no front-end, inclusive de PWAs instaláveis (veja nosso guia de HTML5 e PWA para mobile). Se você está começando na área, entenda primeiro o que faz um desenvolvedor front-end e depois escolha um curso no nosso guia de cursos de front-end. Para referência diária, o MDN tem documentação em português, e o web.dev tem um curso gratuito de design responsivo.

Um exercício que vale mais que dez tutoriais: pegue um site que você usa, abra no celular, anote o que é ruim e reconstrua aquela página com as técnicas acima.

Perguntas frequentes

O que é design responsivo?

É a prática de construir uma única página que se adapta a qualquer tamanho de tela, do celular ao monitor ultrawide, usando layouts flexíveis, unidades relativas, media queries e imagens responsivas, em vez de manter versões separadas para mobile e desktop.

Quais breakpoints usar em 2026?

Não existe lista oficial. Em vez de copiar tamanhos de aparelhos, coloque o breakpoint onde o seu conteúdo quebra. Como ponto de partida, muita gente usa algo perto de 40rem, 48rem, 64rem e 80rem, e ajusta conforme o layout.

Qual a diferença entre media query e container query?

Media query reage ao tamanho da janela do navegador. Container query reage ao tamanho do elemento pai do componente. Container queries são ideais para componentes reutilizáveis, como cards, que aparecem em lugares de larguras diferentes.

Ainda preciso de framework como Bootstrap para fazer site responsivo?

Não. CSS Grid, Flexbox, container queries e clamp() resolvem quase tudo de forma nativa. Frameworks como Tailwind ajudam na produtividade, mas não são necessários para um layout responsivo.


Leia também