乐闻世界logo
搜索文章和话题

TailwindCSS 的暗色模式(Dark Mode)如何实现?

2月17日 14:36

TailwindCSS 的暗色模式(Dark Mode)功能允许开发者轻松实现深色主题,支持自动检测系统偏好和手动切换两种方式。

暗色模式配置

1. 启用暗色模式

tailwind.config.js 中配置暗色模式策略。

javascript
// tailwind.config.js module.exports = { // 使用 class 策略(手动切换) darkMode: 'class', // 或使用 media 策略(自动检测系统偏好) darkMode: 'media', // 或同时支持两种方式 darkMode: ['class', 'media'], }

2. 策略选择

class 策略

  • 需要手动添加 dark 类到 HTML 元素
  • 支持用户手动切换主题
  • 更灵活,适合需要主题切换的应用

media 策略

  • 自动检测系统颜色偏好
  • 无需手动切换
  • 适合不需要主题切换的应用

使用暗色模式

1. 基础用法

html
<!-- 使用 dark: 前缀 --> <div class="bg-white dark:bg-gray-800 text-gray-900 dark:text-white"> 支持暗色模式的内容 </div> <!-- 按钮示例 --> <button class=" bg-blue-500 hover:bg-blue-600 dark:bg-blue-600 dark:hover:bg-blue-700 text-white "> 按钮 </button> <!-- 卡片示例 --> <div class=" bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 "> <h3 class="text-gray-900 dark:text-white font-bold mb-2"> 卡片标题 </h3> <p class="text-gray-600 dark:text-gray-300"> 卡片内容 </p> </div>

2. 完整页面示例

html
<!DOCTYPE html> <html class="dark"> <head> <title>暗色模式示例</title> </head> <body class="bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-white"> <!-- 导航栏 --> <nav class=" bg-white dark:bg-gray-800 shadow-md px-6 py-4 "> <div class="max-w-7xl mx-auto flex justify-between items-center"> <h1 class="text-xl font-bold">Logo</h1> <button id="theme-toggle"> 切换主题 </button> </div> </nav> <!-- 主要内容 --> <main class="max-w-7xl mx-auto px-6 py-8"> <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> <!-- 卡片 --> <div class=" bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 "> <h3 class="text-gray-900 dark:text-white font-bold mb-2"> 卡片标题 </h3> <p class="text-gray-600 dark:text-gray-300"> 卡片内容 </p> </div> </div> </main> </body> </html>

实现主题切换

1. JavaScript 实现

javascript
// 主题切换函数 function toggleTheme() { const html = document.documentElement; if (html.classList.contains('dark')) { html.classList.remove('dark'); localStorage.setItem('theme', 'light'); } else { html.classList.add('dark'); localStorage.setItem('theme', 'dark'); } } // 初始化主题 function initTheme() { const savedTheme = localStorage.getItem('theme'); const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; if (savedTheme === 'dark' || (!savedTheme && prefersDark)) { document.documentElement.classList.add('dark'); } else { document.documentElement.classList.remove('dark'); } } // 监听系统主题变化 window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => { if (!localStorage.getItem('theme')) { if (e.matches) { document.documentElement.classList.add('dark'); } else { document.documentElement.classList.remove('dark'); } } }); // 初始化 initTheme();

2. React 实现

jsx
import { useState, useEffect } from 'react'; function ThemeToggle() { const [isDark, setIsDark] = useState(false); useEffect(() => { // 初始化主题 const savedTheme = localStorage.getItem('theme'); const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; if (savedTheme === 'dark' || (!savedTheme && prefersDark)) { setIsDark(true); document.documentElement.classList.add('dark'); } }, []); const toggleTheme = () => { setIsDark(!isDark); if (!isDark) { document.documentElement.classList.add('dark'); localStorage.setItem('theme', 'dark'); } else { document.documentElement.classList.remove('dark'); localStorage.setItem('theme', 'light'); } }; return ( <button onClick={toggleTheme} className=" px-4 py-2 rounded bg-gray-200 dark:bg-gray-700 text-gray-800 dark:text-white hover:bg-gray-300 dark:hover:bg-gray-600 " > {isDark ? '☀️ 亮色模式' : '🌙 暗色模式'} </button> ); }

3. Vue 实现

vue
<template> <button @click="toggleTheme" class=" px-4 py-2 rounded bg-gray-200 dark:bg-gray-700 text-gray-800 dark:text-white hover:bg-gray-300 dark:hover:bg-gray-600 " > {{ isDark ? '☀️ 亮色模式' : '🌙 暗色模式' }} </button> </template> <script> export default { data() { return { isDark: false, }; }, mounted() { this.initTheme(); }, methods: { initTheme() { const savedTheme = localStorage.getItem('theme'); const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; if (savedTheme === 'dark' || (!savedTheme && prefersDark)) { this.isDark = true; document.documentElement.classList.add('dark'); } }, toggleTheme() { this.isDark = !this.isDark; if (this.isDark) { document.documentElement.classList.add('dark'); localStorage.setItem('theme', 'dark'); } else { document.documentElement.classList.remove('dark'); localStorage.setItem('theme', 'light'); } }, }, }; </script>

暗色模式最佳实践

1. 颜色设计

javascript
// tailwind.config.js module.exports = { theme: { extend: { colors: { // 定义暗色模式专用颜色 gray: { 50: '#f9fafb', 100: '#f3f4f6', 200: '#e5e7eb', 300: '#d1d5db', 400: '#9ca3af', 500: '#6b7280', 600: '#4b5563', 700: '#374151', 800: '#1f2937', 900: '#111827', 950: '#030712', }, }, }, }, }

2. 语义化颜色

html
<!-- 使用语义化颜色 --> <div class=" bg-background dark:bg-background-dark text-primary dark:text-primary-dark border-border dark:border-border-dark "> 语义化颜色 </div>
javascript
// tailwind.config.js module.exports = { theme: { extend: { colors: { background: '#ffffff', 'background-dark': '#1f2937', primary: '#3b82f6', 'primary-dark': '#60a5fa', border: '#e5e7eb', 'border-dark': '#374151', }, }, }, }

3. 渐变和阴影

html
<!-- 暗色模式渐变 --> <div class=" bg-gradient-to-r from-blue-500 to-purple-500 dark:from-blue-600 dark:to-purple-600 "> 渐变背景 </div> <!-- 暗色模式阴影 --> <div class=" shadow-md dark:shadow-xl dark:shadow-gray-900 "> 暗色模式阴影 </div>

高级用法

1. 图片适配

html
<!-- 根据主题显示不同图片 --> <picture> <source srcset="dark-image.png" media="(prefers-color-scheme: dark)"> <img src="light-image.png" alt="自适应图片"> </picture> <!-- 使用 CSS 变量 --> <img src="light-image.png" class="dark:hidden" alt="亮色模式图片" > <img src="dark-image.png" class="hidden dark:block" alt="暗色模式图片" >

2. SVG 图标

html
<!-- 使用 CSS 变量控制 SVG 颜色 --> <svg class="w-6 h-6 text-gray-600 dark:text-gray-300" fill="currentColor"> <path d="..."/> </svg>

3. 动画过渡

html
<!-- 添加平滑过渡 --> <div class=" bg-white dark:bg-gray-800 text-gray-900 dark:text-white transition-colors duration-300 "> 平滑过渡 </div>

常见问题

1. 闪烁问题

在页面加载时可能出现主题闪烁,可以通过以下方式解决:

html
<!-- 在 head 中添加内联脚本 --> <script> if (localStorage.getItem('theme') === 'dark' || (!localStorage.getItem('theme') && window.matchMedia('(prefers-color-scheme: dark)').matches)) { document.documentElement.classList.add('dark'); } </script>

2. 第三方库兼容性

某些第三方库可能不支持暗色模式,需要手动适配:

css
/* 为第三方库添加暗色模式支持 */ .dark .third-party-component { background-color: #1f2937; color: #f9fafb; }

3. 性能优化

避免在暗色模式中使用过多的阴影和渐变,以提升性能。

注意事项

  1. 可访问性:确保暗色模式下的对比度符合 WCAG 标准
  2. 用户偏好:尊重用户的系统偏好设置
  3. 持久化:使用 localStorage 保存用户的主题选择
  4. 平滑过渡:为颜色变化添加过渡效果
  5. 测试覆盖:在不同设备和浏览器上测试暗色模式

总结

TailwindCSS 的暗色模式功能提供了:

  • 简单易用的 API
  • 灵活的配置选项
  • 良好的开发体验
  • 完善的浏览器支持

通过合理使用暗色模式,可以为用户提供更好的视觉体验,同时提升应用的现代感和专业性。

标签:Tailwind CSS