06. 暗色模式
06. 暗色模式
1. 什么是暗色模式
暗色模式(Dark Mode)是一种界面配色方案,使用深色背景和浅色文字,相比传统的亮色模式:
- ✅ 减少眼睛疲劳(尤其在夜间)
- ✅ 节省 OLED 屏幕电量
- ✅ 提供视觉选择
- ✅ 符合现代设计趋势
亮色模式 暗色模式
┌─────────────┐ ┌─────────────┐
│ 白色背景 │ │ 深灰背景 │
│ 黑色文字 │ │ 浅色文字 │
│ 浅色卡片 │ │ 深色卡片 │
└─────────────┘ └─────────────┘
2. Tailwind 暗色模式
2.1 启用暗色模式
Tailwind v4 默认支持暗色模式,无需额外配置。使用 dark: 前缀即可。
<!-- 亮色模式:白色背景 + 黑色文字 -->
<!-- 暗色模式:深灰背景 + 白色文字 -->
<div class="bg-white text-black dark:bg-gray-900 dark:text-white">
内容
</div>
2.2 工作原理
Tailwind 通过 CSS 的 prefers-color-scheme 媒体查询或 .dark 类来切换:
/* 亮色模式 */
.bg-white { background-color: white; }
/* 暗色模式 - 根据系统偏好或父元素 .dark 类 */
@media (prefers-color-scheme: dark) {
.dark\:bg-gray-900 { background-color: #111827; }
}
/* 或使用 .dark 类选择器 */
.dark .dark\:bg-gray-900 { background-color: #111827; }
3. 暗色模式策略
3.1 策略一:跟随系统(默认)
根据用户操作系统设置自动切换:
<!-- 系统是暗色模式时生效 -->
<div class="bg-white dark:bg-gray-900">
跟随系统
</div>
特点:无需用户手动切换,自动适配系统偏好。
3.2 策略二:手动切换
通过 JavaScript 控制 .dark 类来切换:
<!-- HTML 结构 -->
<html class="dark">
<body class="bg-white dark:bg-gray-900">
...
</body>
</html>
// 切换暗色模式
function toggleDarkMode() {
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');
}
}
// 初始化时读取用户偏好
const savedTheme = localStorage.getItem('theme');
if (savedTheme === 'dark') {
document.documentElement.classList.add('dark');
} else if (savedTheme === 'light') {
document.documentElement.classList.remove('dark');
} else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.classList.add('dark');
}
4. 暗色模式完整示例
4.1 基础页面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
<title>暗色模式示例</title>
<style>
/* 确保暗色模式切换时背景平滑过渡 */
body {
transition: background-color 0.3s ease;
}
</style>
</head>
<body class="bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100">
<div class="container mx-auto px-4 py-8">
<!-- 切换按钮 -->
<div class="flex justify-end mb-8">
<button
id="theme-toggle"
class="px-4 py-2 bg-gray-200 dark:bg-gray-700 rounded-lg hover:bg-gray-300 dark:hover:bg-gray-600 transition"
>
🌙 暗色模式
</button>
</div>
<!-- 卡片组件 -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6">
<h2 class="text-xl font-bold mb-2">卡片标题</h2>
<p class="text-gray-600 dark:text-gray-400">
这是一段描述文字,在暗色模式下会自动调整颜色。
</p>
</div>
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6">
<h2 class="text-xl font-bold mb-2">另一个卡片</h2>
<p class="text-gray-600 dark:text-gray-400">
暗色模式下,背景变深,文字变浅。
</p>
</div>
</div>
</div>
<script>
const toggleBtn = document.getElementById('theme-toggle');
const html = document.documentElement;
// 初始化
const savedTheme = localStorage.getItem('theme');
if (savedTheme === 'dark') {
html.classList.add('dark');
toggleBtn.textContent = '☀️ 亮色模式';
} else if (savedTheme === 'light') {
html.classList.remove('dark');
toggleBtn.textContent = '🌙 暗色模式';
} else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
html.classList.add('dark');
toggleBtn.textContent = '☀️ 亮色模式';
}
// 切换
toggleBtn.addEventListener('click', () => {
if (html.classList.contains('dark')) {
html.classList.remove('dark');
localStorage.setItem('theme', 'light');
toggleBtn.textContent = '🌙 暗色模式';
} else {
html.classList.add('dark');
localStorage.setItem('theme', 'dark');
toggleBtn.textContent = '☀️ 亮色模式';
}
});
</script>
</body>
</html>
5. 暗色模式常用类
5.1 背景色
| 亮色模式 | 暗色模式 | 说明 |
|---|---|---|
bg-white |
dark:bg-gray-900 |
页面背景 |
bg-gray-100 |
dark:bg-gray-800 |
卡片/面板背景 |
bg-gray-200 |
dark:bg-gray-700 |
按钮/输入框背景 |
5.2 文字颜色
| 亮色模式 | 暗色模式 | 说明 |
|---|---|---|
text-gray-900 |
dark:text-gray-100 |
主要文字 |
text-gray-700 |
dark:text-gray-300 |
次要文字 |
text-gray-500 |
dark:text-gray-400 |
辅助文字 |
5.3 边框颜色
| 亮色模式 | 暗色模式 | 说明 |
|---|---|---|
border-gray-200 |
dark:border-gray-700 |
边框颜色 |
border-gray-300 |
dark:border-gray-600 |
分割线 |
5.4 阴影
<!-- 亮色模式有阴影,暗色模式阴影更淡 -->
<div class="shadow-md dark:shadow-gray-900/20">
内容
</div>
6. 常见暗色模式模式
6.1 导航栏
<nav class="bg-white dark:bg-gray-900 shadow-md">
<div class="container mx-auto px-4 py-3">
<div class="flex justify-between items-center">
<div class="text-xl font-bold text-gray-900 dark:text-white">Logo</div>
<div class="space-x-4">
<a href="#" class="text-gray-700 dark:text-gray-300 hover:text-blue-500">首页</a>
<a href="#" class="text-gray-700 dark:text-gray-300 hover:text-blue-500">关于</a>
</div>
</div>
</div>
</nav>
6.2 卡片
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6">
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">卡片标题</h3>
<p class="text-gray-600 dark:text-gray-400 mt-2">卡片描述文字</p>
<button class="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
按钮
</button>
</div>
6.3 表单输入
<input
type="text"
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600
bg-white dark:bg-gray-800 text-gray-900 dark:text-white
rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
placeholder="输入内容"
>
6.4 下拉菜单
<select class="px-3 py-2 border border-gray-300 dark:border-gray-600
bg-white dark:bg-gray-800 text-gray-900 dark:text-white rounded">
<option>选项1</option>
<option>选项2</option>
</select>
7. 暗色模式颜色映射
7.1 推荐配色方案
| 元素 | 亮色模式 | 暗色模式 |
|---|---|---|
| 页面背景 | bg-gray-50 |
dark:bg-gray-950 |
| 卡片背景 | bg-white |
dark:bg-gray-900 |
| 主要文字 | text-gray-900 |
dark:text-gray-50 |
| 次要文字 | text-gray-600 |
dark:text-gray-400 |
| 边框 | border-gray-200 |
dark:border-gray-800 |
| 链接 | text-blue-600 |
dark:text-blue-400 |
7.2 颜色强度对应
亮色模式:数值越小颜色越浅
- 50: 最浅(几乎白色)
- 100-300: 浅色
- 400-600: 中等
- 700-900: 深色
- 950: 最深(几乎黑色)
暗色模式:数值越小颜色越深
- 50: 最深
- 100-300: 深色
- 400-600: 中等
- 700-900: 浅色
- 950: 最浅
8. 自定义暗色模式样式
8.1 配置暗色模式策略
在 tailwind.config.js 中:
module.exports = {
darkMode: 'class', // 使用 .dark 类切换
// 或 darkMode: 'media' // 跟随系统
}
8.2 自定义暗色模式颜色
module.exports = {
theme: {
extend: {
colors: {
dark: {
bg: '#0f0f0f',
surface: '#1a1a1a',
border: '#2a2a2a',
}
}
}
}
}
<div class="bg-white dark:bg-dark-bg">
自定义暗色模式背景
</div>
9. 避免暗色模式常见问题
9.1 图片处理
<!-- 图片在暗色模式下可能需要调整亮度 -->
<img src="logo.png" class="dark:brightness-90">
9.2 阴影处理
<!-- 暗色模式下阴影应该更淡 -->
<div class="shadow-md dark:shadow-gray-900/20">
9.3 滚动条
/* 自定义滚动条暗色模式 */
.dark ::-webkit-scrollbar-track {
background: #1f2937;
}
.dark ::-webkit-scrollbar-thumb {
background: #4b5563;
}
10. 练习
练习 1:暗色模式卡片
实现一个支持暗色模式的用户卡片:
- 亮色:白色背景、深色文字
- 暗色:深灰背景、浅色文字
- 包含头像、姓名、职位、按钮
参考答案:
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 max-w-sm">
<div class="flex items-center gap-4 mb-4">
<div class="w-12 h-12 bg-blue-500 rounded-full"></div>
<div>
<h3 class="font-bold text-gray-900 dark:text-white">张三</h3>
<p class="text-gray-600 dark:text-gray-400">前端工程师</p>
</div>
</div>
<button class="w-full py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
联系
</button>
</div>
练习 2:暗色模式切换按钮
实现一个切换按钮,显示当前模式图标
参考答案:
<button id="theme-toggle" class="p-2 rounded-lg bg-gray-200 dark:bg-gray-700">
<span class="dark:hidden">🌙</span>
<span class="hidden dark:inline">☀️</span>
</button>
11. 总结
| 概念 | 说明 |
|---|---|
dark: 前缀 |
暗色模式下生效的样式 |
| 跟随系统 | 默认,使用 prefers-color-scheme |
| 手动切换 | 使用 .dark 类控制 |
| 存储偏好 | localStorage 保存用户选择 |
| 颜色映射 | 亮色用浅色,暗色用深色 |
一句话总结:
暗色模式用
dark:前缀定义深色样式,通过系统偏好或.dark类自动切换。
Tailwind 里重复写 dark: 确实挺烦的,有几种方法可以避免。
方法一:使用 CSS 变量 + 主题切换(推荐)
在 CSS 中定义变量,Tailwind 类名只写一次:
/* style.css */
:root {
--bg: #ffffff;
--text: #1a1a1a;
}
.dark {
--bg: #1a1a1a;
--text: #f5f5f5;
}
<div class="bg-[var(--bg)] text-[var(--text)]">
内容
</div>
方法二:自定义 Tailwind 插件
创建 dark-utils.js:
// tailwind.config.js
module.exports = {
plugins: [
function({ addUtilities }) {
addUtilities({
'.card': {
backgroundColor: 'white',
color: 'black',
'@media (prefers-color-scheme: dark)': {
backgroundColor: '#1f2937',
color: '#f3f4f6',
},
},
})
},
],
}
使用时只需一个类:<div class="card">
方法三:使用 PostCSS 嵌套
用 PostCSS 嵌套语法,把暗色样式写在一起:
.card {
@apply bg-white text-gray-900;
.dark & {
@apply bg-gray-800 text-gray-100;
}
}
需要安装 postcss-nested。
方法四:CSS 变量 + Tailwind 任意值(最简洁)
/* style.css */
:root {
--color-bg: theme('colors.white');
--color-text: theme('colors.gray.900');
}
.dark {
--color-bg: theme('colors.gray.800');
--color-text: theme('colors.gray.100');
}
<div class="bg-[var(--color-bg)] text-[var(--color-text)]">
内容
</div>
方法五:设计系统层面解决
定义语义化 CSS 变量,而不是直接用颜色:
:root {
--surface-primary: #ffffff;
--surface-secondary: #f5f5f5;
--text-primary: #1a1a1a;
}
.dark {
--surface-primary: #1e1e1e;
--surface-secondary: #2d2d2d;
--text-primary: #ffffff;
}
然后所有组件统一使用变量,颜色切换只改变量,组件代码完全不用动。
我的建议
如果项目规模不大,方法四最实用;如果要长期维护,方法五是更干净的设计系统方案。
你倾向于哪种?我可以帮你配置好。
12. 下一步
掌握了暗色模式后,接下来学习如何自定义主题:
👉 下一节:07. 自定义主题
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)