Tailwind需配置darkMode: 'media'或'darkMode: 'class'才能启用dark:前缀;前者依赖系统偏好,后者通过JS控制html元素class实现手动切换,并需内联脚本防闪屏。

如何用 prefers-color-scheme 检测系统暗黑偏好
浏览器原生支持通过 @media (prefers-color-scheme: dark) 读取系统设置,Tailwind 默认已启用该特性,但前提是你的 tailwind.config.js 中启用了 darkMode: 'media'。不配这个,dark: 前缀完全不会生效。
常见错误是只写了 dark:bg-gray-800 却没配 darkMode,结果样式始终不触发。
-
darkMode: 'media'→ 完全依赖系统偏好,无法手动切换 -
darkMode: 'class'→ 需手动给添加dark类,适合加开关控制 - 别漏掉
content配置里包含所有用到dark:的模板文件,否则 JIT 模式下类名可能被剔除
用 darkMode: 'class' 实现可切换的暗黑模式
这是最常用也最可控的方式:不绑定系统,由 JS 控制 ,Tailwind 自动应用所有 dark: 变体。
关键点在于必须把 dark 类加在 上(不是 ),否则 dark: 选择器无法匹配到子元素。
立即学习“前端免费学习笔记(深入)”;
- 初始化时建议从
localStorage读取上次用户选择, fallback 到prefers-color-scheme - 切换时用
document.documentElement.classList.toggle('dark'),避免覆盖其他可能存在的类 - 记得同步写入
localStorage,否则刷新就重置
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
按钮切换时怎么避免闪屏(FOUC)
页面加载瞬间默认亮色,JS 执行后才切暗色,肉眼可见“闪一下”。根本原因是 HTML 渲染早于 JS 运行。
解决思路是让初始状态由服务端或内联脚本决定,而不是等外部 JS。
- 在
里放一段内联<script></script>,立即读localStorage并操作documentElement - 不要用
DOMContentLoaded或load事件延迟执行 —— 太晚了 - 如果用框架(如 React),需在 SSR 或 hydration 前就确定主题,否则客户端首次渲染仍会闪
dark: 类和普通类的优先级与覆盖逻辑
Tailwind 生成的 dark: CSS 规则默认带 [class~="dark"] 前缀,所以 dark:bg-gray-800 编译为 .dark .dark\:bg-gray-800(注意转义)。这意味着它依赖父级有 dark 类,且层级比普通类深一级 —— 所以同名普通类不会被意外覆盖。
但要注意:如果你写了 bg-gray-100 dark:bg-gray-900,两者都会生成;而 bg-gray-100 在非暗色下生效,dark:bg-gray-900 在 下生效。没有隐式互斥,只是条件不同。
- 不要指望
dark:类自动清除普通类 —— 它们共存,靠 CSS 优先级和作用域区分 - 如果需要“仅暗色下生效”,就只写
dark:bg-gray-800,不配对应亮色类 - 自定义颜色或间距等需同时配置
darkMode对应的 theme 扩展,否则dark:shadow-xl可能无效
真正麻烦的是跨设备同步状态,比如用户在桌面设为暗色,手机却还是亮色 —— 这得靠账号体系或更精细的 localStorage + service worker 缓存策略,Tailwind 本身不处理这个。


















