必须选 class 模式,因 media 模式无法手动切换且不记用户选择;darkmode: 'class' 需确保 dark 类真实作用于 根元素,并配合 localstorage 持久化与跨标签页同步,同时深色下颜色体系需完整重定义。

必须选 class,除非你明确只要系统自动同步、且不提供任何手动开关。 因为 media 看似省事,但一上线就卡在「用户无法主动切」和「无法记住上次选择」两个硬伤上——尤其对登录态、表单页、管理后台这类场景,几乎不可用。
怎么配 darkMode: 'class' 才算生效
只改 tailwind.config.js 不够,必须让 dark 类真实出现在 根元素上,Tailwind 才会启用对应规则。常见漏掉的环节:
- 配置写了
darkMode: 'class',但 HTML 里没加dark类,或加在了上(无效) - 用了框架(如 Vue/React),但没在挂载前/服务端渲染时同步设置根节点类名,导致首屏闪白/闪黑
- 没处理 localStorage 持久化,刷新后回到默认浅色(
默认无dark)
最小可行验证:直接在 HTML 中写 ,然后用 bg-white dark:bg-gray-900 测试背景是否变黑。
darkMode: 'media' 的真实行为边界
它只监听 @media (prefers-color-scheme: dark),完全绕过 JS 和 HTML 类控制。这意味着:
- 你写
完全没用,Tailwind 忽略它 - 用户在 macOS / iOS 系统设置里关掉深色模式,你的页面立刻变亮,哪怕你 JS 里强行加了
dark类 - Chrome 开发者工具的「Rendering」面板里可以强制触发
prefers-color-scheme,但这是模拟,不是真实用户行为
适合场景极少:比如纯静态博客、无交互 landing page,且你确定所有目标用户都接受系统级统一控制。
切换按钮 + 记住用户选择的最小实现
核心是三件事:读取偏好、写入根节点、存到 localStorage。不需要额外插件:
- 初始化时先查
localStorage.getItem('theme'),有值就设到document.documentElement.classList;没值则 fallback 到window.matchMedia('(prefers-color-scheme: dark)').matches - 按钮点击时,用
classList.toggle('dark')切换,并同步写入localStorage - 务必监听
storage事件,用于跨 tab 同步(否则用户在另一个标签页切了主题,当前页不会响应)
示例关键行:document.documentElement.classList.add('dark')、localStorage.setItem('theme', 'dark')、window.addEventListener('storage', ...)。
最易忽略的点:深色模式不是“加个 dark 类就完事”,而是整个颜色体系要重新设计。比如 text-gray-700 在深色下可能还是太暗,得配合 dark:text-gray-300;自定义颜色(如 primary)必须在 theme.extend.colors 里同时定义浅/深两套值,否则 JIT 编译时不会生成深色版本工具类。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











