Tailwind CSS 暗色模式 #

启用暗色模式 #

配置方式 #

javascript
// tailwind.config.js
module.exports = {
  darkMode: 'media', // 或 'class'
}

media 模式 #

根据系统偏好自动切换:

javascript
// tailwind.config.js
module.exports = {
  darkMode: 'media',
}
html
<!-- 自动跟随系统 -->
<div class="bg-white dark:bg-gray-800 text-gray-900 dark:text-white">
  自动适配暗色模式
</div>

class 模式 #

手动控制暗色模式:

javascript
// tailwind.config.js
module.exports = {
  darkMode: 'class',
}
html
<!-- 手动添加 dark 类 -->
<html class="dark">
  <body class="bg-white dark:bg-gray-900">
    暗色模式内容
  </body>
</html>

暗色模式类 #

基本用法 #

html
<!-- 背景 -->
<div class="bg-white dark:bg-gray-800">背景颜色</div>

<!-- 文字 -->
<p class="text-gray-900 dark:text-white">文字颜色</p>

<!-- 边框 -->
<div class="border border-gray-200 dark:border-gray-700">边框颜色</div>

组合使用 #

html
<div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-6 shadow-md dark:shadow-gray-900/50">
  <h3 class="text-gray-900 dark:text-white font-semibold">卡片标题</h3>
  <p class="text-gray-600 dark:text-gray-300 mt-2">卡片内容描述</p>
</div>

实现暗色模式切换 #

JavaScript 切换 #

html
<!DOCTYPE html>
<html>
<head>
  <script>
    // 检查本地存储或系统偏好
    if (localStorage.getItem('theme') === 'dark' || 
        (!localStorage.getItem('theme') && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
      document.documentElement.classList.add('dark')
    } else {
      document.documentElement.classList.remove('dark')
    }
  </script>
</head>
<body>
  <button id="theme-toggle" class="p-2 rounded-lg bg-gray-200 dark:bg-gray-700">
    <svg class="w-6 h-6 hidden dark:block" fill="currentColor" viewBox="0 0 20 20">
      <path d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z"></path>
    </svg>
    <svg class="w-6 h-6 block dark:hidden" fill="currentColor" viewBox="0 0 20 20">
      <path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z"></path>
    </svg>
  </button>

  <script>
    const themeToggle = document.getElementById('theme-toggle')
    
    themeToggle.addEventListener('click', () => {
      document.documentElement.classList.toggle('dark')
      localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light')
    })
  </script>
</body>
</html>

React 实现 #

jsx
import { useState, useEffect } from 'react'

function ThemeToggle() {
  const [isDark, setIsDark] = useState(false)

  useEffect(() => {
    const isDark = localStorage.getItem('theme') === 'dark' || 
                   (!localStorage.getItem('theme') && window.matchMedia('(prefers-color-scheme: dark)').matches)
    setIsDark(isDark)
    document.documentElement.classList.toggle('dark', isDark)
  }, [])

  const toggleTheme = () => {
    const newIsDark = !isDark
    setIsDark(newIsDark)
    document.documentElement.classList.toggle('dark', newIsDark)
    localStorage.setItem('theme', newIsDark ? 'dark' : 'light')
  }

  return (
    <button onClick={toggleTheme} className="p-2 rounded-lg bg-gray-200 dark:bg-gray-700">
      {isDark ? '🌙' : '☀️'}
    </button>
  )
}

Vue 实现 #

vue
<template>
  <button @click="toggleTheme" class="p-2 rounded-lg bg-gray-200 dark:bg-gray-700">
    {{ isDark ? '🌙' : '☀️' }}
  </button>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const isDark = ref(false)

onMounted(() => {
  isDark.value = localStorage.getItem('theme') === 'dark' || 
                 (!localStorage.getItem('theme') && window.matchMedia('(prefers-color-scheme: dark)').matches)
  document.documentElement.classList.toggle('dark', isDark.value)
})

const toggleTheme = () => {
  isDark.value = !isDark.value
  document.documentElement.classList.toggle('dark', isDark.value)
  localStorage.setItem('theme', isDark.value ? 'dark' : 'light')
}
</script>

实战示例 #

暗色模式页面 #

html
<!DOCTYPE html>
<html class="scroll-smooth">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>暗色模式示例</title>
  <script src="https://cdn.tailwindcss.com"></script>
  <script>
    tailwind.config = {
      darkMode: 'class',
    }
  </script>
</head>
<body class="bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-gray-100 min-h-screen">
  <!-- 导航栏 -->
  <nav class="bg-white dark:bg-gray-800 shadow sticky top-0">
    <div class="container mx-auto px-4 py-4 flex justify-between items-center">
      <span class="font-bold text-xl">Logo</span>
      <button id="theme-toggle" class="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700">
        <span class="dark:hidden">🌙</span>
        <span class="hidden dark:inline">☀️</span>
      </button>
    </div>
  </nav>

  <!-- 主内容 -->
  <main class="container mx-auto px-4 py-8">
    <div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6">
      <h1 class="text-2xl font-bold mb-4">暗色模式示例</h1>
      <p class="text-gray-600 dark:text-gray-300">
        这是一个支持暗色模式的页面示例。
      </p>
    </div>
  </main>
</body>
</html>

暗色模式卡片 #

html
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-md dark:shadow-gray-900/50 p-6 border border-gray-200 dark:border-gray-700">
  <h3 class="text-lg font-semibold text-gray-900 dark:text-white">卡片标题</h3>
  <p class="text-gray-600 dark:text-gray-300 mt-2">卡片内容描述</p>
  <button class="mt-4 bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded">
    操作按钮
  </button>
</div>

暗色模式表单 #

html
<form class="space-y-4">
  <div>
    <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
      用户名
    </label>
    <input class="w-full border border-gray-300 dark:border-gray-600 rounded-lg px-4 py-2 bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-transparent">
  </div>
  <div>
    <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
      密码
    </label>
    <input type="password" class="w-full border border-gray-300 dark:border-gray-600 rounded-lg px-4 py-2 bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-transparent">
  </div>
  <button class="w-full bg-blue-500 hover:bg-blue-600 text-white py-2 rounded-lg">
    登录
  </button>
</form>

暗色模式表格 #

html
<div class="overflow-x-auto">
  <table class="w-full">
    <thead class="bg-gray-50 dark:bg-gray-700">
      <tr>
        <th class="px-4 py-3 text-left text-gray-700 dark:text-gray-300">名称</th>
        <th class="px-4 py-3 text-left text-gray-700 dark:text-gray-300">状态</th>
        <th class="px-4 py-3 text-left text-gray-700 dark:text-gray-300">操作</th>
      </tr>
    </thead>
    <tbody class="divide-y divide-gray-200 dark:divide-gray-700">
      <tr class="hover:bg-gray-50 dark:hover:bg-gray-800">
        <td class="px-4 py-3">项目 1</td>
        <td class="px-4 py-3">
          <span class="px-2 py-1 text-xs rounded-full bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200">
            活跃
          </span>
        </td>
        <td class="px-4 py-3">
          <button class="text-blue-500 hover:text-blue-600">编辑</button>
        </td>
      </tr>
    </tbody>
  </table>
</div>

最佳实践 #

1. 使用语义化颜色 #

html
<!-- 推荐 -->
<div class="bg-surface dark:bg-surface-dark">
  <p class="text-primary dark:text-primary-dark">内容</p>
</div>

<!-- 配置
module.exports = {
  theme: {
    extend: {
      colors: {
        surface: '#ffffff',
        'surface-dark': '#1f2937',
        primary: '#1f2937',
        'primary-dark': '#f9fafb',
      },
    },
  },
}
-->

2. 图片适配 #

html
<!-- 暗色模式使用不同图片 -->
<img class="dark:hidden" src="logo-light.png" alt="Logo">
<img class="hidden dark:block" src="logo-dark.png" alt="Logo">

3. 避免硬编码颜色 #

html
<!-- 不推荐 -->
<div class="bg-white dark:bg-gray-900">
  <p class="text-gray-900 dark:text-white">内容</p>
</div>

<!-- 推荐:使用 CSS 变量 -->
<div class="bg-background text-foreground">
  <p>内容</p>
</div>

下一步 #

掌握暗色模式后,继续学习 自定义配置 了解如何扩展 Tailwind CSS!

最后更新:2026-03-28