必须将 darkMode: 'class' 设为配置文件顶层字段,否则 dark: 类名不生效;需手动在 document.documentElement 添加 dark 类,并结合 localStorage 与系统偏好同步状态,且暗色样式须单独设计而非简单反转。

必须在 tailwind.config.js(或 tailwind.config.ts)中显式设置 darkMode: 'class',否则所有 dark: 类名都会被忽略——连警告都不报,样式直接失效。
darkMode 配置写在哪、怎么写才生效
很多人把 darkMode: 'class' 放在 theme 或 plugins 里,甚至写成 darkMode: true 或 darkMode: 'dark',这些全无效。它必须是顶层字段,且值只能是字符串 'class' 或 'media':
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./app/**/*.{js,ts,jsx,tsx}"],
darkMode: 'class', // ✅ 唯一正确位置和写法
theme: {
extend: {},
},
plugins: [],
}
- 写错位置或值 →
dark:bg-gray-800完全不编译进 CSS - 配了
'class'却没手动加dark类到→ 暗黑样式永远不触发 - 别混用:不能同时依赖系统偏好又配
'class',darkMode字段只认一个值
为什么必须操作 document.documentElement 而不是 body
Tailwind 默认检查的是 元素上是否有 dark 类。如果只给 加类,dark: 规则不会匹配——这是最常被忽略的细节。
- Next.js App Router 的 Hydration 逻辑依赖
html上的 class 状态,改body会导致首屏闪白或 SSR 不一致 - 服务端渲染时,
document.body在 Node 环境下不存在,直接调用会报错;document.documentElement同样不可用,所以切换逻辑必须放在客户端执行 - localStorage 存取 +
document.documentElement.classList.toggle('dark', flag)是唯一能跨刷新、跨框架(Next.js/Nuxt)稳定工作的组合
切换逻辑里最容易漏掉的三件事
光写个 toggleDark() 函数远远不够。实际部署中,以下三点缺一不可:
- 首次加载时就读取
localStorage.theme并同步到document.documentElement,否则用户刷新页面就回到默认模式 - 如果
localStorage.theme是'system'或未设置,需 fallback 到window.matchMedia('(prefers-color-scheme: dark)').matches - 每次切换后必须同时更新
localStorage.theme和document.documentElement,不能只改其一
示例(可直接塞进 layout.tsx 的 里):
(() => {
try {
const stored = localStorage.getItem('theme')
const prefersDark = window.matchMedia?.('(prefers-color-scheme: dark)').matches
const shouldDark = stored === 'dark' || (stored !== 'light' && prefersDark)
document.documentElement.classList.toggle('dark', shouldDark)
} catch {}
})()
暗黑模式不是颜色反转,别硬套 bg-white → dark:bg-black
直接把亮色背景换成纯黑、文字换成纯白,会导致对比度过高、阅读疲劳。Tailwind 的 dark: 不是魔法开关,而是样式入口——你仍需为暗色场景单独设计颜色层级。
-
bg-white在暗色下不该映射为dark:bg-black,而应是dark:bg-slate-900或dark:bg-gray-950 - 文字颜色同理:
text-gray-900对应的暗色不一定是dark:text-white,更常用dark:text-gray-100或dark:text-slate-200 - 组件如代码块、表格、表单控件,需要分别定义暗色下的 border、shadow、placeholder 颜色,不能只靠一层
dark:
真正难的从来不是加 dark: 前缀,而是想清楚:这个颜色在暗环境下承担什么角色?它和相邻元素的对比度是否合理?
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











