必须显式配置 darkmode: 'class' 或 darkmode: 'media',否则 dark: 类在构建时被完全删除;切换需操作 document.documentelement.classlist 并同步 localstorage;初始化脚本须内联于 中早于 css 解析。

必须显式配置 darkMode: 'class' 或 darkMode: 'media',否则所有 dark: 类在构建时被完全删除——不是失效,是压根没生成 CSS。
tailwind.config.js 里 darkMode 必须是顶层字段且值合法
常见错误包括:darkMode: true、darkMode: 'dark'、把 darkMode 写进 theme.extend,或 TypeScript 配置中类型未导出导致配置未加载。v4 仍只接受两个字符串值:'media' 或 'class'。漏配或错配后,哪怕写了 dark:bg-gray-900,最终 CSS 文件里也找不到它。
切换时只能操作 document.documentElement.classList
document.body.classList.toggle('dark') 是无效的,尤其在 Next.js、Nuxt 等 SSR 框架中会引发 hydration mismatch 或首屏闪白。Tailwind 默认只检查 元素上的 dark 类, 上的类不触发 dark: 变体。
- 正确写法:
document.documentElement.classList.toggle('dark') - 切换后必须同步更新
localStorage.setItem('theme', 'dark'),否则刷新即丢失状态 - SSR 渲染时无法读取客户端
localStorage,所以服务端需 fallback 到window.matchMedia(但该 API 在 Node.js 中不可用,实际需靠初始 HTML 注入)
初始化脚本必须内联在 中立即执行
“闪白”本质是浏览器先渲染无 dark 类的样式,再等 JS 执行才加类。用 DOMContentLoaded 或 useEffect 都太晚。
- 必须把初始化逻辑写成内联
<script></script>,放在里、CSS<link>之前 - 最小可行代码(可直接粘贴):
(() => { 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 {} })() - 不能依赖框架生命周期,必须原生、无依赖、早于任何样式解析
最容易被忽略的是:v4 并未改变 v3 的核心约束——dark: 仍是硬编码绑定到系统媒体查询或 html.dark 类,不识别 data-theme="dark";想支持多主题,必须绕过 dark:,改用 CSS 变量 + @layer base + safelist。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











