Design Responsivo com Tailwind CSS: Sistema de Breakpoints e Estratégia Mobile-First

Sistema de Breakpoints

O Tailwind fornece 5 breakpoints padrão. Você pode usar prefixos responsivos para aplicar estilos direcionados a diferentes tamanhos de tela.

Prefixo Largura Mínima Media Query CSS Dispositivos Típicos
sm: 640px @media (min-width: 640px) Celular paisagem
md: 768px @media (min-width: 768px) Tablet
lg: 1024px @media (min-width: 1024px) Notebook
xl: 1280px @media (min-width: 1280px) Monitor desktop
2xl: 1536px @media (min-width: 1536px) Monitor grande

CSS Tradicional vs Tailwind A abordagem tradicional exige escrever múltiplas consultas @media e manter os estilos em diferentes arquivos, enquanto o Tailwind usa prefixos como sm: e md: para declarar estilos responsivos diretamente no HTML.

Estratégia Mobile-First

O Tailwind adota uma estratégia Mobile-First: estilos sem prefixo são aplicados às telas menores por padrão, e prefixos de breakpoints maiores sobrescrevem os estilos de telas menores.

Exemplo

HTML
<!DOCTYPE html>
<html lang="pt-br">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Estratégia Mobile-First</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-gray-100 p-4 md:p-8">
  <div class="max-w-6xl mx-auto space-y-8">
    <!-- Texto responsivo -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Tamanho de Fonte Responsivo</h3>
      <p class="text-sm md:text-base lg:text-lg xl:text-xl">
        Telas pequenas usam text-sm por padrão, telas médias text-base, telas grandes text-lg e telas extra-grandes text-xl
      </p>
    </div>

    <!-- Padding responsivo -->
    <div class="bg-blue-100 rounded-lg p-2 sm:p-4 md:p-6 lg:p-8">
      <p class="text-center text-blue-800">Padding responsivo: p-2 → sm:p-4 → md:p-6 → lg:p-8</p>
    </div>

    <!-- Mostrar/ocultar responsivo -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Mostrar/Ocultar Responsivo</h3>
      <div class="block md:hidden bg-red-100 p-4 rounded text-center text-red-700">
        Visível apenas em telas pequenas (block md:hidden)
      </div>
      <div class="hidden md:block bg-green-100 p-4 rounded text-center text-green-700">
        Visível em telas médias e acima (hidden md:block)
      </div>
    </div>
  </div>
</body>
</html>
▶ Experimente
💡 Dica: Mobile-First significa que estilos sem prefixo são a linha de base, e prefixos de breakpoints são usados para melhorias. Por exemplo, text-sm md:text-lg significa 14px em telas pequenas e 18px em telas médias e acima.

Prefixo Responsivo na Prática

Prefixos responsivos podem ser combinados com qualquer classe do Tailwind para alterar o layout em diferentes tamanhos de tela.

Exemplo

HTML
<!DOCTYPE html>
<html lang="pt-br">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Prefixo Responsivo na Prática</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-gray-100 p-4 md:p-8">
  <div class="max-w-6xl mx-auto space-y-8">
    <!-- Layout Flex responsivo -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Layout Flex Responsivo</h3>
      <div class="flex flex-col sm:flex-row gap-4">
        <div class="flex-1 bg-blue-100 p-4 rounded text-center">Item 1</div>
        <div class="flex-1 bg-blue-200 p-4 rounded text-center">Item 2</div>
        <div class="flex-1 bg-blue-300 p-4 rounded text-center">Item 3</div>
      </div>
      <p class="text-sm text-gray-500 mt-2">Empilhado verticalmente em telas pequenas (flex-col), horizontal em telas médias (sm:flex-row)</p>
    </div>

    <!-- Colunas de Grid responsivas -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Colunas de Grid Responsivas</h3>
      <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
        <div class="bg-green-100 p-4 rounded text-center">1</div>
        <div class="bg-green-200 p-4 rounded text-center">2</div>
        <div class="bg-green-300 p-4 rounded text-center">3</div>
        <div class="bg-green-400 p-4 rounded text-center">4</div>
        <div class="bg-green-500 p-4 rounded text-center text-white">5</div>
        <div class="bg-green-600 p-4 rounded text-center text-white">6</div>
        <div class="bg-green-700 p-4 rounded text-center text-white">7</div>
        <div class="bg-green-800 p-4 rounded text-center text-white">8</div>
      </div>
      <p class="text-sm text-gray-500 mt-2">grid-cols-1 → sm:grid-cols-2 → lg:grid-cols-3 → xl:grid-cols-4</p>
    </div>

    <!-- Espaçamento responsivo -->
    <div class="bg-white rounded-lg shadow p-4 sm:p-6 md:p-8">
      <h3 class="font-semibold mb-2 sm:mb-4 md:mb-6">Espaçamento Responsivo</h3>
      <div class="space-y-2 sm:space-y-4 md:space-y-6">
        <div class="bg-purple-100 p-4 rounded">Item A</div>
        <div class="bg-purple-200 p-4 rounded">Item B</div>
        <div class="bg-purple-300 p-4 rounded">Item C</div>
      </div>
    </div>
  </div>
</body>
</html>
▶ Experimente

CSS Tradicional vs Tailwind A abordagem tradicional exige escrever múltiplos blocos CSS como @media (min-width: 768px) { .grid { grid-template-columns: repeat(2, 1fr); } }, enquanto o Tailwind faz o mesmo em uma única linha com grid-cols-1 md:grid-cols-2 lg:grid-cols-3.

Imagens Responsivas

Imagens responsivas garantem que as imagens sejam exibidas corretamente em diferentes tamanhos de tela, evitando transbordamento ou distorção.

Exemplo

HTML
<!DOCTYPE html>
<html lang="pt-br">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Imagens Responsivas</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-gray-100 p-4 md:p-8">
  <div class="max-w-6xl mx-auto space-y-8">
    <!-- Largura de imagem responsiva -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Largura de Imagem Responsiva</h3>
      <img src="https://picsum.photos/1200/400" alt="Imagem responsiva"
           class="w-full md:w-3/4 lg:w-1/2 mx-auto rounded-lg">
      <p class="text-sm text-gray-500 mt-2 text-center">w-full → md:w-3/4 → lg:w-1/2</p>
    </div>

    <!-- Grid de imagens responsivo -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Grid de Imagens Responsivo</h3>
      <div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2 md:gap-4">
        <img src="https://picsum.photos/300/300?random=1" alt="Imagem 1" class="w-full aspect-square object-cover rounded-lg">
        <img src="https://picsum.photos/300/300?random=2" alt="Imagem 2" class="w-full aspect-square object-cover rounded-lg">
        <img src="https://picsum.photos/300/300?random=3" alt="Imagem 3" class="w-full aspect-square object-cover rounded-lg">
        <img src="https://picsum.photos/300/300?random=4" alt="Imagem 4" class="w-full aspect-square object-cover rounded-lg">
        <img src="https://picsum.photos/300/300?random=5" alt="Imagem 5" class="w-full aspect-square object-cover rounded-lg">
        <img src="https://picsum.photos/300/300?random=6" alt="Imagem 6" class="w-full aspect-square object-cover rounded-lg">
        <img src="https://picsum.photos/300/300?random=7" alt="Imagem 7" class="w-full aspect-square object-cover rounded-lg">
        <img src="https://picsum.photos/300/300?random=8" alt="Imagem 8" class="w-full aspect-square object-cover rounded-lg">
      </div>
    </div>
  </div>
</body>
</html>
▶ Experimente
💡 Dica: Use w-full para garantir que as imagens não ultrapassem o contêiner pai, combinado com object-cover para manter a proporção.

Tabelas Responsivas

Tabelas responsivas podem rolar horizontalmente em telas pequenas, evitando que o conteúdo seja espremido.

Exemplo

HTML
<!DOCTYPE html>
<html lang="pt-br">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Tabelas Responsivas</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-gray-100 p-4 md:p-8">
  <div class="max-w-6xl mx-auto">
    <div class="bg-white rounded-lg shadow p-4 md:p-6">
      <h3 class="font-semibold mb-4">Tabela Responsiva</h3>
      <div class="overflow-x-auto">
        <table class="w-full text-sm md:text-base">
          <thead>
            <tr class="bg-gray-100">
              <th class="p-2 md:p-3 text-left">ID</th>
              <th class="p-2 md:p-3 text-left">Nome</th>
              <th class="p-2 md:p-3 text-left hidden sm:table-cell">E-mail</th>
              <th class="p-2 md:p-3 text-left hidden md:table-cell">Telefone</th>
              <th class="p-2 md:p-3 text-left">Status</th>
            </tr>
          </thead>
          <tbody>
            <tr class="border-b">
              <td class="p-2 md:p-3">001</td>
              <td class="p-2 md:p-3">Alice</td>
              <td class="p-2 md:p-3 hidden sm:table-cell">alice@exemplo.com</td>
              <td class="p-2 md:p-3 hidden md:table-cell">138-0000-0001</td>
              <td class="p-2 md:p-3"><span class="bg-green-100 text-green-700 px-2 py-1 rounded text-xs">Ativo</span></td>
            </tr>
            <tr class="border-b">
              <td class="p-2 md:p-3">002</td>
              <td class="p-2 md:p-3">Bob</td>
              <td class="p-2 md:p-3 hidden sm:table-cell">bob@exemplo.com</td>
              <td class="p-2 md:p-3 hidden md:table-cell">138-0000-0002</td>
              <td class="p-2 md:p-3"><span class="bg-yellow-100 text-yellow-700 px-2 py-1 rounded text-xs">Pendente</span></td>
            </tr>
            <tr class="border-b">
              <td class="p-2 md:p-3">003</td>
              <td class="p-2 md:p-3">Charlie</td>
              <td class="p-2 md:p-3 hidden sm:table-cell">charlie@exemplo.com</td>
              <td class="p-2 md:p-3 hidden md:table-cell">138-0000-0003</td>
              <td class="p-2 md:p-3"><span class="bg-red-100 text-red-700 px-2 py-1 rounded text-xs">Desativado</span></td>
            </tr>
          </tbody>
        </table>
      </div>
      <p class="text-sm text-gray-500 mt-4">Algumas colunas ficam ocultas em telas pequenas; a tabela rola horizontalmente</p>
    </div>
  </div>
</body>
</html>
▶ Experimente

CSS Tradicional vs Tailwind A abordagem tradicional exige escrever consultas @media para controlar a visibilidade das colunas da tabela, enquanto o Tailwind usa nomes de classes como hidden sm:table-cell para declarar isso diretamente.

Container Queries (@container)

Container queries aplicam estilos com base no tamanho do contêiner pai, em vez do tamanho da viewport. Este é um novo recurso suportado no Tailwind v4.

Exemplo

HTML
<!DOCTYPE html>
<html lang="pt-br">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Container Queries</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-gray-100 p-4 md:p-8">
  <div class="max-w-6xl mx-auto space-y-8">
    <!-- Conceitos básicos de container query -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Conceitos Básicos de Container Query</h3>
      <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
        <!-- Contêiner pequeno -->
        <div class="@container bg-gray-50 rounded-lg p-4 border-2 border-dashed border-gray-300">
          <div class="flex flex-col @md:flex-row gap-4">
            <img src="https://picsum.photos/150/150" alt="Avatar" class="w-20 h-20 @md:w-24 @md:h-24 rounded-full object-cover">
            <div>
              <h4 class="font-semibold @md:text-lg">Nome de Usuário</h4>
              <p class="text-gray-600 text-sm @md:text-base">Este é um exemplo de container query. O layout muda com base na largura do contêiner pai.</p>
            </div>
          </div>
          <p class="text-xs text-gray-400 mt-2">Contêiner pequeno: layout vertical</p>
        </div>

        <!-- Contêiner grande -->
        <div class="@container bg-gray-50 rounded-lg p-4 border-2 border-dashed border-gray-300">
          <div class="flex flex-col @md:flex-row gap-4">
            <img src="https://picsum.photos/150/150" alt="Avatar" class="w-20 h-20 @md:w-24 @md:h-24 rounded-full object-cover">
            <div class="flex-1">
              <h4 class="font-semibold @md:text-lg">Nome de Usuário</h4>
              <p class="text-gray-600 text-sm @md:text-base">Container queries usam a classe @container e prefixos como @md: para aplicar estilos com base no tamanho do contêiner pai.</p>
              <div class="hidden @lg:flex gap-2 mt-2">
                <span class="bg-blue-100 text-blue-700 px-2 py-1 rounded text-xs">Tag 1</span>
                <span class="bg-green-100 text-green-700 px-2 py-1 rounded text-xs">Tag 2</span>
              </div>
            </div>
          </div>
          <p class="text-xs text-gray-400 mt-2">Contêiner grande: layout horizontal com tags extras</p>
        </div>
      </div>
    </div>

    <!-- Cards com container query -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Cards com Container Query</h3>
      <div class="grid grid-cols-1 md:grid-cols-3 gap-6">
        <div class="@container bg-gray-50 rounded-lg overflow-hidden border">
          <img src="https://picsum.photos/400/200?random=10" alt="Imagem do card" class="w-full h-32 @sm:h-48 object-cover">
          <div class="p-4">
            <h4 class="font-semibold @sm:text-lg">Título do Card</h4>
            <p class="text-gray-600 text-sm @sm:text-base mt-2">Container queries permitem que componentes respondam ao tamanho do próprio contêiner, em vez do tamanho da viewport.</p>
            <button class="hidden @sm:block mt-4 bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700">Saiba Mais</button>
          </div>
        </div>
        <div class="@container bg-gray-50 rounded-lg overflow-hidden border">
          <img src="https://picsum.photos/400/200?random=11" alt="Imagem do card" class="w-full h-32 @sm:h-48 object-cover">
          <div class="p-4">
            <h4 class="font-semibold @sm:text-lg">Título do Card</h4>
            <p class="text-gray-600 text-sm @sm:text-base mt-2">Isso permite que os componentes respondam corretamente em diferentes layouts, tornando-os mais flexíveis.</p>
            <button class="hidden @sm:block mt-4 bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700">Saiba Mais</button>
          </div>
        </div>
        <div class="@container bg-gray-50 rounded-lg overflow-hidden border">
          <img src="https://picsum.photos/400/200?random=12" alt="Imagem do card" class="w-full h-32 @sm:h-48 object-cover">
          <div class="p-4">
            <h4 class="font-semibold @sm:text-lg">Título do Card</h4>
            <p class="text-gray-600 text-sm @sm:text-base mt-2">Use a classe @container para marcar contêineres, e prefixos como @sm: e @md: para aplicar estilos.</p>
            <button class="hidden @sm:block mt-4 bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700">Saiba Mais</button>
          </div>
        </div>
      </div>
    </div>
  </div>
</body>
</html>
▶ Experimente

CSS Tradicional vs Tailwind Container queries tradicionais exigem escrever media queries como @container (min-width: 400px) { ... }, enquanto o Tailwind usa a classe @container e prefixos como @sm: e @md: para declará-las diretamente.

💡 Dica: Os prefixos de breakpoints para container queries usam @xs: (20rem), @sm: (24rem), @md: (28rem), @lg: (32rem), @xl: (36rem), @2xl: (42rem).

❓ Perguntas Frequentes

P: A ordem dos prefixos responsivos importa? R: Sim. O Tailwind segue uma estratégia Mobile-First, então os prefixos de breakpoints entram em vigor do menor para o maior. Por exemplo, com text-sm md:text-base lg:text-lg, breakpoints maiores sobrescrevem os estilos de breakpoints menores.

P: Como oculto um elemento em um tamanho de tela específico? R: Use uma combinação de hidden e block. Por exemplo, hidden md:block oculta em telas pequenas e mostra em telas médias; block md:hidden mostra em telas pequenas e oculta em telas médias.

P: Qual a diferença entre container queries e media queries? R: Media queries (sm:, md:, etc.) respondem à largura da viewport; container queries (@container, @sm:, etc.) respondem à largura do contêiner pai. Container queries são mais adequadas para componentes reutilizáveis que precisam de comportamento responsivo em diferentes layouts.

P: Como personalizo os breakpoints? R: No Tailwind v4, use a diretiva @theme para personalizar os breakpoints. Por exemplo, @theme { --breakpoint-tablet: 768px; } e depois use o prefixo tablet:.

📖 Resumo

📝 Exercícios

  1. ⭐ Crie uma barra de navegação responsiva: use um menu hambúrguer em telas pequenas (block md:hidden), e mostre a navegação completa em telas médias (hidden md:flex)

  2. ⭐⭐ Crie um grid de cards de produto responsivo: 1 coluna em telas pequenas (grid-cols-1), 2 colunas em telas médias (md:grid-cols-2), 4 colunas em telas grandes (lg:grid-cols-4), com cards que aumentam ao passar o mouse (hover:scale-105)

  3. ⭐⭐⭐ Crie um layout de painel responsivo: use container queries para um componente de barra lateral que colapsa para ícones em contêineres estreitos (@lg: mostra texto) e se expande para mostrar o texto completo do menu em contêineres largos

100%