darkMode 必须配置在 tailwind.config.js 根级,仅支持 'media' 或 'class';dark: 类生效需 html 元素含 dark 类;SSR 下需内联脚本在 head 中初始化并持久化 localStorage。

darkMode 配置必须显式写在 tailwind.config.js 顶层
不写 darkMode 字段,或写成 darkMode: true、darkMode: 'dark',所有 dark: 类都会被 Tailwind 编译器直接丢弃——连警告都不抛。只接受两个合法值:'media' 或 'class'。
常见错误是把它塞进 theme 对象里,或者当成插件配置项。正确位置是 tailwind.config.js 的根级:
module.exports = {
darkMode: 'class', // ✅ 正确
// darkMode: 'media', // ✅ 也可选
content: [...],
theme: { ... }
}
改完必须重启构建服务(如 npm run dev),Tailwind 不热更配置。
dark: 类生效的前提是 html 元素有 dark 类
dark:bg-gray-800 不会自己触发切换,它只在祖先元素(默认是 <html>)带 dark 类时才启用。加在 <body> 上无效,尤其在 SSR 框架(Next.js/Nuxt)中会导致 hydration 失败或首屏闪白。
立即学习“前端免费学习笔记(深入)”;
- 验证是否生效:直接在 HTML 中写
<html class="dark">,再测bg-white dark:bg-gray-900 - 手动切换用
document.documentElement.classList.toggle('dark'),不是body - SSR 环境下注意:服务端无
window,JS 初始化逻辑需包裹if (typeof window !== 'undefined')或放在客户端生命周期钩子中
避免首屏“闪白”必须内联执行初始化脚本
浏览器先渲染浅色样式,等 JS 执行完才加 dark 类——这个延迟就是闪白。解决方案是在 CSS 加载前就决定是否加类,脚本必须放在 <head> 内联,且不能包在 DOMContentLoaded 里(太晚了)。
PigX UI Pro 前端开发指南 - Vue 3 + TypeScript + Element Plus。当用户提到 PigX UI、PigX 前端、lgb-mgui 项目、Vue 3 企业级后台开发、Element Plus 后台开发时使用此技能。
最小可行逻辑(可直接贴入 <head>):
(() => {
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 {}
})()
这个脚本同时处理三种状态:'light'(强制亮色)、'dark'(强制暗色)、其他值(跟随系统)。
localStorage 持久化不是可选,而是体验底线
用户点一次开关,刷新就回到默认浅色,等于没做。每次切换后必须同步写入:
- 开启深色:
localStorage.setItem('theme', 'dark') - 关闭深色:
localStorage.setItem('theme', 'light') - 若想支持“跟随系统”,存
'system',并在初始化时用matchMedia判断
别用 cookie 或 URL 参数替代——前者增加请求开销,后者会让分享链接带上主题状态,污染语义。
真正容易被忽略的是:SSR 渲染时无法读取 localStorage,客户端 hydration 前的 DOM 状态和 JS 初始化必须严格对齐,否则水合警告或视觉跳变不可避免。

















