Tailwind CSS CSS 前端 技术分享

用 CSS 变量实现优雅的深色模式切换

Series: 独立开发技术栈 #2

为什么不用 Tailwind 的 dark mode?

Tailwind CSS 提供了 dark: 前缀来实现深色模式,比如 dark:bg-gray-800 dark:text-white。这种方式简单直观,但在实际项目中存在几个痛点:每个元素都需要写两套颜色类名,HTML 变得冗长;颜色分散在各个组件中,后期调整主题非常困难;如果要支持多个主题(不只是明暗两种),扩展性很差。

CSS 变量方案

我采用的方案是通过 CSS 变量 + data-theme 属性 来管理主题。在 theme.css 中定义两套变量:

[data-theme="light"] {
  --color-bg: #f7f9fe;
  --color-text: #4c4948;
  --color-accent: #425AEF;
}

[data-theme="dark"] {
  --color-bg: #18171d;
  --color-text: #cddcdc;
  --color-accent: #f2b94b;
}

然后在 Tailwind 中直接使用 bg-[var(--color-bg)]text-[var(--color-text)] 等。切换主题时只需改变 <html> 标签上的 data-theme 属性,所有颜色自动更新。

localStorage 持久化

用户的主题偏好通过 localStorage 保存。同时在页面加载前(放在 <head> 中的内联脚本)立即读取并应用,避免闪烁:

const saved = localStorage.getItem('theme');
const prefersDark = matchMedia('(prefers-color-scheme: dark)').matches;
const theme = saved || (prefersDark ? 'dark' : 'light');
document.documentElement.setAttribute('data-theme', theme);

prefers-color-scheme 兼容

当用户没有手动设置过主题时,自动跟随系统偏好。这样既尊重了用户的系统设置,又保留了手动切换的灵活性。

这套方案的优势在于:颜色集中管理、HTML 简洁、扩展性好。如果未来想增加更多主题色,只需新增一组 CSS 变量即可,组件代码无需任何修改。

Series: 独立开发技术栈