Tailwind CSS Modo Escuro e Configuração de Tema: Prefixo dark e Diretiva @theme

Modo Escuro (dark:)

O Tailwind usa o prefixo dark: para definir estilos para o modo escuro, suportando as estratégias media e class.

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>Demonstração do Modo Escuro</title>
  <script src="https://cdn.tailwindcss.com"></script>
  <script>
    tailwind.config = {
      darkMode: 'class'
    }
  </script>
</head>
<body class="min-h-screen bg-white dark:bg-gray-900 transition-colors">
  <div class="max-w-4xl mx-auto p-8 space-y-8">
    <!-- Botão de alternância do modo escuro -->
    <div class="flex justify-end">
      <button onclick="document.documentElement.classList.toggle('dark')"
              class="p-2 rounded-lg bg-gray-200 dark:bg-gray-700 text-gray-800 dark:text-gray-200">
        Alternar Modo Escuro
      </button>
    </div>

    <!-- Cores de texto -->
    <div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6">
      <h3 class="text-gray-900 dark:text-white font-semibold text-lg mb-4">Cores de Texto</h3>
      <p class="text-gray-600 dark:text-gray-300">
        Este texto aparece em cinza escuro no modo claro e cinza claro no modo escuro.
      </p>
      <p class="text-blue-600 dark:text-blue-400 mt-2">
        As cores dos links também se adaptam com base no modo.
      </p>
    </div>

    <!-- Componentes de card -->
    <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
      <div class="bg-white dark:bg-gray-800 rounded-lg shadow-lg dark:shadow-gray-700/50 p-6">
        <div class="w-12 h-12 bg-blue-100 dark:bg-blue-900 rounded-lg flex items-center justify-center mb-4">
          <span class="text-blue-600 dark:text-blue-400 text-xl">🎨</span>
        </div>
        <h4 class="text-gray-900 dark:text-white font-semibold mb-2">Adaptação de Tema</h4>
        <p class="text-gray-600 dark:text-gray-400">Fundos, sombras e cores de texto dos cards se adaptam ao modo escuro.</p>
      </div>
      <div class="bg-white dark:bg-gray-800 rounded-lg shadow-lg dark:shadow-gray-700/50 p-6">
        <div class="w-12 h-12 bg-green-100 dark:bg-green-900 rounded-lg flex items-center justify-center mb-4">
          <span class="text-green-600 dark:text-green-400 text-xl">✨</span>
        </div>
        <h4 class="text-gray-900 dark:text-white font-semibold mb-2">Transições Suaves</h4>
        <p class="text-gray-600 dark:text-gray-400">Combinado com transition-colors para uma troca de cores suave.</p>
      </div>
    </div>

    <!-- Elementos de formulário -->
    <div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6">
      <h3 class="text-gray-900 dark:text-white font-semibold mb-4">Elementos de Formulário</h3>
      <div class="space-y-4">
        <input type="text" placeholder="Campo de entrada"
               class="w-full p-3 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white placeholder-gray-400 dark:placeholder-gray-500 focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400">
        <button class="w-full p-3 bg-blue-600 dark:bg-blue-500 text-white rounded-lg hover:bg-blue-700 dark:hover:bg-blue-600 transition-colors">
          Botão de Envio
        </button>
      </div>
    </div>
  </div>
</body>
</html>
▶ Experimente

CSS Tradicional vs Tailwind A abordagem tradicional requer escrever @media (prefers-color-scheme: dark) ou adicionar manualmente classes .dark com diversas regras CSS, enquanto o Tailwind usa prefixos como dark:bg-gray-900 dark:text-white para declarações inline.

💡 Dica: A estratégia darkMode: 'class' requer alternar a classe dark no elemento <html>. A estratégia darkMode: 'media' segue automaticamente a preferência do sistema.

Tema Personalizado (tailwind.config)

Você pode estender ou sobrescrever o tema padrão através do arquivo tailwind.config, adicionando cores personalizadas, fontes, espaçamentos e mais.

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>Demonstração de Tema Personalizado</title>
  <script src="https://cdn.tailwindcss.com"></script>
  <script>
    tailwind.config = {
      theme: {
        extend: {
          colors: {
            primary: {
              50: '#eff6ff',
              100: '#dbeafe',
              200: '#bfdbfe',
              300: '#93c5fd',
              400: '#60a5fa',
              500: '#3b82f6',
              600: '#2563eb',
              700: '#1d4ed8',
              800: '#1e40af',
              900: '#1e3a8a',
            },
            accent: '#f59e0b',
            brand: '#8b5cf6',
          },
          fontFamily: {
            sans: ['Inter', 'system-ui', 'sans-serif'],
            display: ['Poppins', 'sans-serif'],
          },
          spacing: {
            '128': '32rem',
            '144': '36rem',
          },
          borderRadius: {
            '4xl': '2rem',
          },
        },
      },
    }
  </script>
</head>
<body class="min-h-screen bg-gray-100 p-8">
  <div class="max-w-4xl mx-auto space-y-8">
    <!-- Cores personalizadas -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Cores Personalizadas</h3>
      <div class="flex flex-wrap gap-4">
        <div class="w-20 h-20 bg-primary-500 rounded-lg flex items-center justify-center text-white text-xs">primary-500</div>
        <div class="w-20 h-20 bg-primary-600 rounded-lg flex items-center justify-center text-white text-xs">primary-600</div>
        <div class="w-20 h-20 bg-primary-700 rounded-lg flex items-center justify-center text-white text-xs">primary-700</div>
        <div class="w-20 h-20 bg-accent rounded-lg flex items-center justify-center text-white text-xs">accent</div>
        <div class="w-20 h-20 bg-brand rounded-lg flex items-center justify-center text-white text-xs">brand</div>
      </div>
    </div>

    <!-- Fontes personalizadas -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Fontes Personalizadas</h3>
      <p class="font-sans text-lg mb-2">font-sans: Usando a fonte Inter</p>
      <p class="font-display text-lg">font-display: Usando a fonte Poppins</p>
    </div>

    <!-- Espaçamento personalizado -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Espaçamento Personalizado</h3>
      <div class="space-y-2">
        <div class="h-4 bg-primary-200 rounded" style="width: 32rem;">
          <span class="text-xs">w-128 (32rem)</span>
        </div>
        <div class="h-4 bg-primary-300 rounded" style="width: 36rem;">
          <span class="text-xs">w-144 (36rem)</span>
        </div>
      </div>
    </div>

    <!-- Border radius personalizado -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Border Radius Personalizado</h3>
      <div class="flex gap-4">
        <div class="w-24 h-24 bg-brand rounded-4xl flex items-center justify-center text-white text-xs">rounded-4xl</div>
        <div class="w-24 h-24 bg-accent rounded-full flex items-center justify-center text-white text-xs">rounded-full</div>
      </div>
    </div>
  </div>
</body>
</html>
▶ Experimente

CSS Tradicional vs Tailwind A abordagem tradicional requer definir diversas variáveis e classes em CSS, enquanto o Tailwind estende o tema através da opção extend no tailwind.config, gerando automaticamente as classes utilitárias correspondentes.

Diretiva @theme (Nova Funcionalidade do v4)

O Tailwind v4 introduz a diretiva @theme, usando sintaxe nativa CSS para definir variáveis de tema sem precisar de um arquivo de configuração JavaScript.

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>Demonstração da Diretiva @theme</title>
  <script src="https://cdn.tailwindcss.com"></script>
  <style type="text/tailwindcss">
    @theme {
      --color-primary-50: #eff6ff;
      --color-primary-100: #dbeafe;
      --color-primary-200: #bfdbfe;
      --color-primary-300: #93c5fd;
      --color-primary-400: #60a5fa;
      --color-primary-500: #3b82f6;
      --color-primary-600: #2563eb;
      --color-primary-700: #1d4ed8;
      --color-primary-800: #1e40af;
      --color-primary-900: #1e3a8a;

      --color-accent: #f59e0b;
      --color-brand: #8b5cf6;

      --font-sans: 'Inter', system-ui, sans-serif;
      --font-display: 'Poppins', sans-serif;

      --spacing-128: 32rem;
      --spacing-144: 36rem;

      --radius-4xl: 2rem;
    }
  </style>
</head>
<body class="min-h-screen bg-gray-100 p-8">
  <div class="max-w-4xl mx-auto space-y-8">
    <!-- Cores definidas com @theme -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Cores Definidas com @theme</h3>
      <div class="flex flex-wrap gap-4">
        <div class="w-20 h-20 bg-primary-500 rounded-lg flex items-center justify-center text-white text-xs">primary-500</div>
        <div class="w-20 h-20 bg-primary-600 rounded-lg flex items-center justify-center text-white text-xs">primary-600</div>
        <div class="w-20 h-20 bg-accent rounded-lg flex items-center justify-center text-white text-xs">accent</div>
        <div class="w-20 h-20 bg-brand rounded-lg flex items-center justify-center text-white text-xs">brand</div>
      </div>
    </div>

    <!-- Fontes definidas com @theme -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Fontes Definidas com @theme</h3>
      <p class="font-sans text-lg mb-2">font-sans: Usando a fonte Inter</p>
      <p class="font-display text-lg">font-display: Usando a fonte Poppins</p>
    </div>

    <!-- Espaçamentos definidos com @theme -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Espaçamentos Definidos com @theme</h3>
      <div class="space-y-2">
        <div class="h-4 bg-primary-200 rounded w-128">
          <span class="text-xs">w-128 (32rem)</span>
        </div>
        <div class="h-4 bg-primary-300 rounded w-144">
          <span class="text-xs">w-144 (36rem)</span>
        </div>
      </div>
    </div>

    <!-- Border radius definido com @theme -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Border Radius Definido com @theme</h3>
      <div class="flex gap-4">
        <div class="w-24 h-24 bg-brand rounded-4xl flex items-center justify-center text-white text-xs">rounded-4xl</div>
      </div>
    </div>
  </div>
</body>
</html>
▶ Experimente

CSS Tradicional vs Tailwind A abordagem tradicional requer definir temas usando objetos JavaScript no tailwind.config.js, enquanto a diretiva @theme do Tailwind v4 usa sintaxe de variáveis nativas CSS, que é mais intuitiva e compatível com variáveis CSS nativas.

💡 Dica: Os nomes das variáveis na diretiva @theme seguem convenções como --color-*, --font-*, --spacing-*, --radius-*, etc. O Tailwind gera automaticamente as classes utilitárias correspondentes.

Variáveis CSS Nativas e Integração com Tailwind

O Tailwind v4 suporta o uso de variáveis CSS nativas diretamente, sem precisar de um arquivo de configuraçã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>Integração com Variáveis CSS Nativas</title>
  <script src="https://cdn.tailwindcss.com"></script>
  <style>
    :root {
      --main-bg: #f8fafc;
      --card-bg: #ffffff;
      --text-primary: #1e293b;
      --text-secondary: #64748b;
      --border-color: #e2e8f0;
      --spacing-section: 2rem;
    }

    .dark {
      --main-bg: #0f172a;
      --card-bg: #1e293b;
      --text-primary: #f1f5f9;
      --text-secondary: #94a3b8;
      --border-color: #334155;
    }
  </style>
</head>
<body class="min-h-screen p-8" style="background-color: var(--main-bg);">
  <div class="max-w-4xl mx-auto space-y-8" style="gap: var(--spacing-section);">
    <!-- Alternância do modo escuro -->
    <div class="flex justify-end">
      <button onclick="document.documentElement.classList.toggle('dark')"
              class="p-2 rounded-lg" style="background-color: var(--card-bg); color: var(--text-primary);">
        Alternar Modo Escuro
      </button>
    </div>

    <!-- Card usando variáveis CSS -->
    <div class="rounded-lg shadow p-6" style="background-color: var(--card-bg); border: 1px solid var(--border-color);">
      <h3 class="font-semibold text-lg mb-4" style="color: var(--text-primary);">Variáveis CSS Nativas</h3>
      <p style="color: var(--text-secondary);">
        Este card usa variáveis CSS nativas para definir cores, aplicadas via atributo style.
      </p>
    </div>

    <!-- Uso misto -->
    <div class="rounded-lg shadow p-6 bg-white dark:bg-gray-800">
      <h3 class="font-semibold text-lg mb-4 text-gray-900 dark:text-white">Uso Misto</h3>
      <p class="text-gray-600 dark:text-gray-300 mb-4">
        Você pode usar classes do Tailwind e variáveis CSS juntas.
      </p>
      <div class="flex gap-4">
        <div class="w-16 h-16 rounded-lg" style="background-color: var(--text-primary);"></div>
        <div class="w-16 h-16 rounded-lg bg-blue-500"></div>
        <div class="w-16 h-16 rounded-lg" style="background-color: var(--border-color);"></div>
      </div>
    </div>
  </div>
</body>
</html>
▶ Experimente
💡 Dica: As variáveis CSS nativas são mais adequadas para valores que precisam ser modificados dinamicamente em tempo de execução (como troca de tema), enquanto as classes do Tailwind são ideais para estilos estáticos.

Introdução ao Sistema de Plugins

Os plugins do Tailwind podem estender a funcionalidade do framework, adicionando classes utilitárias personalizadas, variantes ou estilos base.

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>Demonstração do Sistema de Plugins</title>
  <script src="https://cdn.tailwindcss.com"></script>
  <script>
    const plugin = tailwind.plugin;

    // Plugin personalizado: adicionar classes utilitárias de gradiente de texto
    const textGradientPlugin = plugin(function({ addUtilities }) {
      addUtilities({
        '.text-gradient-blue': {
          'background': 'linear-gradient(to right, #3b82f6, #8b5cf6)',
          '-webkit-background-clip': 'text',
          '-webkit-text-fill-color': 'transparent',
          'background-clip': 'text',
        },
        '.text-gradient-red': {
          'background': 'linear-gradient(to right, #ef4444, #f97316)',
          '-webkit-background-clip': 'text',
          '-webkit-text-fill-color': 'transparent',
          'background-clip': 'text',
        },
      });
    });

    tailwind.config = {
      plugins: [textGradientPlugin],
    }
  </script>
</head>
<body class="min-h-screen bg-gray-100 p-8">
  <div class="max-w-4xl mx-auto space-y-8">
    <!-- Classes utilitárias adicionadas pelo plugin -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Plugin Personalizado: Gradiente de Texto</h3>
      <p class="text-4xl font-bold text-gradient-blue mb-4">Texto com gradiente azul</p>
      <p class="text-4xl font-bold text-gradient-red">Texto com gradiente vermelho</p>
    </div>

    <!-- Exemplos de plugins comuns de terceiros -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Plugins Comuns</h3>
      <div class="space-y-4">
        <div class="p-4 bg-gray-50 rounded-lg">
          <h4 class="font-medium text-gray-900">@tailwindcss/typography</h4>
          <p class="text-gray-600 text-sm">Fornece estilos tipográficos bonitos para conteúdo longo usando a classe prose.</p>
        </div>
        <div class="p-4 bg-gray-50 rounded-lg">
          <h4 class="font-medium text-gray-900">@tailwindcss/forms</h4>
          <p class="text-gray-600 text-sm">Fornece resets de estilo base para elementos de formulário, garantindo comportamento consistente entre navegadores.</p>
        </div>
        <div class="p-4 bg-gray-50 rounded-lg">
          <h4 class="font-medium text-gray-900">@tailwindcss/aspect-ratio</h4>
          <p class="text-gray-600 text-sm">Fornece classes utilitárias de aspect-ratio para controlar a proporção largura/altura dos elementos.</p>
        </div>
      </div>
    </div>
  </div>
</body>
</html>
▶ Experimente

CSS Tradicional vs Tailwind A abordagem tradicional requer escrever manualmente classes CSS e importá-las, enquanto os plugins do Tailwind se integram automaticamente ao processo de build através de APIs como addUtilities, addComponents e addBase.

⚠️ Nota: A API de plugins mudou no Tailwind v4. Recomenda-se usar abordagens nativas CSS para estender funcionalidades. A diretiva @theme e @layer podem substituir a maioria dos casos de uso de plugins.

❓ Perguntas Frequentes

P: Qual é a diferença entre darkMode: 'class' e darkMode: 'media'? R: A estratégia 'media' segue automaticamente a media query prefers-color-scheme do sistema, e o usuário não pode alterná-la manualmente. A estratégia 'class' requer alternar manualmente a classe dark no elemento <html>, sendo adequada para cenários onde um botão de alternância é fornecido.

P: Qual é a diferença entre a diretiva @theme e o tailwind.config? R: O tailwind.config define temas usando objetos JavaScript e requer um arquivo de configuração. A diretiva @theme usa sintaxe de variáveis nativas CSS, definida diretamente no CSS. É uma nova funcionalidade do Tailwind v4 e é a abordagem recomendada.

P: Como uso imagens diferentes no modo escuro? R: Use o prefixo dark: com hidden e block. Por exemplo, <img class="block dark:hidden" src="light.png"> e <img class="hidden dark:block" src="dark.png">.

P: Como devo escolher entre variáveis CSS e classes do Tailwind? R: Prefira classes do Tailwind para estilos estáticos, e use variáveis CSS para valores que precisam ser modificados dinamicamente em tempo de execução. Ambos podem ser misturados, como style="color: var(--text-primary)".

📖 Resumo

📝 Exercícios

  1. ⭐ Crie uma página de login que suporte modo escuro, incluindo campos de entrada, botões e cards, usando o prefixo dark: para adaptar todos os elementos

  2. ⭐⭐ Use a diretiva @theme para personalizar um tema de marca (incluindo cor primária, cor secundária e fontes), e crie uma página de demonstração

  3. ⭐⭐⭐ Crie um alternador de temas que suporte modos claro/escuro/sistema, usando variáveis CSS para troca dinâmica de cores do tema

100%