darkmode 必须显式配置为 'media' 或 'class',否则 dark: 变体被完全忽略;'media' 响应系统偏好,'class' 需手动操作 document.documentelement.classlist 并持久化 localstorage,且初始化脚本须置于 内联执行以避免闪白。

darkMode 配置必须显式写在 tailwind.config.js 里
不写 darkMode 字段,或写成 darkMode: true、darkMode: 'dark',dark: 变体都会被完全忽略——Tailwind 编译时直接丢弃所有带 dark: 的类,连警告都不抛。
只接受两个合法值:'media' 或 'class'。v3 起默认行为虽倾向 'media',但显式声明是唯一可靠做法。
-
darkMode: 'media'→ 样式响应prefers-color-scheme: dark媒体查询,无需 JS,也无法手动干预 -
darkMode: 'class'→dark:只在html(或body)有class="dark"时生效,必须自己加/删类
class 策略下必须操作 document.documentElement
写 document.body.classList.toggle('dark') 是常见错误。Tailwind 默认检查的是 html 元素上的 dark 类,不是 body —— 尤其在 SSR 框架(如 Next.js、Nuxt)中,body 操作会导致 hydration 失败或首屏闪白。
- 正确目标:始终用
document.documentElement.classList.toggle('dark') - 初始化时机:脚本需在 CSS 加载前执行,最好放在
内联 script 中 - 状态持久化:切换后必须同步写入
localStorage.setItem('theme', 'dark'),否则刷新即丢失
首次加载时避免“闪白”需要预判系统偏好
用户打开页面瞬间,浏览器先渲染浅色样式,再等 JS 执行完才切深色——这个延迟就是“闪白”。解决办法是在 HTML 渲染前就决定是否加 dark 类。
最小可行逻辑(可直接贴进 ):
(() => {
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')、跟随系统(null或其他值) - 注意:不能用
DOMContentLoaded包裹,它太晚了
dark: 与其他变体组合时顺序影响可读性
dark:hover:bg-gray-700 和 hover:dark:bg-gray-700 效果一样,但前者更符合直觉:先限定“深色模式下”,再限定“悬停时”。Tailwind 解析器不强制顺序,但团队协作时统一约定能减少歧义。
- 推荐把
dark:放最前面,比如dark:focus:ring-blue-500 - 避免嵌套过深:如
group-hover:dark:bg-gray-800在某些旧版 Tailwind 中可能不生效,优先拆成独立类 - 注意 focus-ring 类在深色背景下的对比度:
focus:ring-blue-500在bg-gray-900上可能看不清,建议配dark:focus:ring-blue-400
darkMode: 'class' 不是开关,它只是告诉 Tailwind “去哪找 dark 类”,而你得确保那个地方真有、且早于样式计算就存在。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











