给 Tailwind CSS 项目开启 Dark Mode:从“能切换”到“写样式”
很多项目“支持暗黑模式”的关键其实只有两件事:
- 如何决定当前是 dark 还是 light
- 如何在代码里写出对应样式。
下面讲给项目(使用tailwind css)开启darkmode的两种主流方式
1) 选择 Dark Mode 策略:class vs media
Tailwind 暗黑模式有两种触发机制:
media:跟随系统设置(prefers-color-scheme: dark),不需要你加类名,但很难做“手动切换”。class:由你给根节点加.dark控制,最适合做“按钮切换/记忆用户偏好”。
一般推荐 class(可控、可持久化、跨端一致)。
Tailwind v3/v4 配置提示
- Tailwind v3:在
tailwind.config.js里配置:
// tailwind.config.js
module.exports = {
darkMode: "class",
// ...
};
- Tailwind v4(CSS-first):你可以在全局 CSS 里定义 dark variant(不同工程模板略有差异),我用的next.js,在
app/globals.css中配置:
/* globals.css */
@custom-variant dark (&:is(.dark *));
2) 启动 Dark Mode:给 <html> 加上 .dark
暗黑模式“生效”的前提是:页面某处(通常是 <html>)存在 .dark 类。
2.1 手动切换实现
在任意地方执行:
document.documentElement.classList.add("dark"); // 开启暗黑
document.documentElement.classList.remove("dark"); // 关闭暗黑
记住用户选择 + 支持跟随系统
核心思路:
- localStorage 存
"light" | "dark" | "system" - 如果是 system 或没存过,就用
prefers-color-scheme - 页面首屏渲染前就决定,避免出现“闪一下”的行为
示例(可放在 Next.js App Router 的 layout.tsx 里 head 的 inline script,或放在你自己的入口 HTML 模板中):
(() => {
try {
const stored = localStorage.getItem("theme"); // "light" | "dark" | "system" | null
const prefersDark =
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches;
const shouldDark =
stored === "dark" || (stored !== "light" && prefersDark);
document.documentElement.classList.toggle("dark", shouldDark);
} catch {}
})();
当用户点击按钮时:
function setTheme(next: "light" | "dark" | "system") {
localStorage.setItem("theme", next);
const prefersDark =
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches;
const shouldDark = next === "dark" || (next === "system" && prefersDark);
document.documentElement.classList.toggle("dark", shouldDark);
}
3) 在代码里写 Dark 样式的两种写法
dark: 前缀
<div className="bg-white text-slate-900 dark:bg-slate-900 dark:text-slate-100">
Hello Dark Mode
</div>
也可与hover,active等属性组合:
<button className="bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700">
Button
</button>
语义化 token(大型项目里)
如果你项目对工程化程度要求高,可以使用类似 shadcn 的变量体系(bg-background, text-foreground 等),暗黑模式就不需要在每个组件写 dark:,而是把颜色映射到 CSS 变量上:
<div className="bg-background text-foreground border-border">
Token-based theming
</div>
然后在全局 CSS 里定义 :root(浅色)和 .dark(暗色)的变量值:
:root {
--background: white;
--foreground: #0f172a;
}
.dark {
--background: #0b1220;
--foreground: #e2e8f0;
}

3235

被折叠的 条评论
为什么被折叠?



