Tailwind 的 dark: 前缀不响应 CSS 变量切换,真正有效的主题方案是:将颜色抽为 CSS 变量,挂载到 :root 或 [data-theme="xxx"] 下,通过 @layer base 声明并确保 data-theme 设在 <html> 标签上。

dark: 前缀根本不会响应 CSS 变量切换
如果你写了 dark:bg-[var(--color-bg)] 但颜色没变,不是编译失败,而是这个写法本身无效。dark: 是 Tailwind 对 prefers-color-scheme: dark 或 class="dark" 的硬编码映射,它不解析括号里的 var(),也不关心你定义了什么 CSS 变量。哪怕你把 data-theme="dark" 写在 上,dark: 依然完全无感。
必须用 data-theme + @layer base + :root 变量声明
真正能响应主题切换的路径只有一条:把所有可变颜色抽成 CSS 变量,并统一挂载到 :root 或 [data-theme="xxx"] 下,再通过 @layer base 声明,确保它们优先级足够高、不被 Tailwind 默认样式覆盖。
-
data-theme必须设在 标签上,比如<html data-theme="dark">,否则子元素继承不到 - 所有变量(如
--color-bg、--color-text)必须写在@layer base块里,不能放在组件 scoped style 或普通<style>中 - 首次渲染前建议内联默认值,例如在
<head>里加<style>:root { --color-bg: #fff; --color-text: #1f2937; }</style>,避免闪动 - JS 切换时用
document.documentElement.setAttribute('data-theme', 'dark'),而不是操作 class
bg-[var(--color-bg)] 过不了 PurgeCSS?加 safelist
Tailwind 默认会剔除无法静态分析的任意值,bg-[var(--color-bg)] 就是典型受害者。不加白名单,构建后压根没这条规则。
- 在
tailwind.config.js的safelist中加入正则:/^bg-\[.*\]$/和/^text-\[.*\]$/ - 变量名中不能有空格,
var(--color-bg)合法,var( --color-bg )会编译失败 - 别混用命名风格——项目里同时存在
--primary、--color-primary、--theme-bg,会导致部分组件换色、部分不动
为什么 text-[var(--color-text)] 有时不生效
不是语法错,而是 CSS 层叠出了问题。Tailwind 生成的 text-gray-700 类会同时设置 color 和 font-weight,一旦和 text-[var(--color-text)] 写在同一元素上,前者大概率覆盖后者。
立即学习“前端免费学习笔记(深入)”;
- 避免混用:要么全走变量路径(
text-[var(--color-text)]),要么全用预设类(text-gray-700 dark:text-gray-200) - 如果必须共存,确保变量类的特异性更高,比如用
text-[var(--color-text)] !important(不推荐),或把预设类移到更外层容器 - 透明度支持要同步处理:
bg-[var(--color-bg)]/70要求变量结构为rgb(var(--color-bg) / var(--color-bg-alpha, 1)),JS 切换时得一并设--color-bg-alpha
setAttribute 时,如果 CSS 还没加载完,浏览器会先按旧变量渲染一帧。内联默认值 + 统一命名 + 全部收口到 @layer base,比写十个切换函数管用得多。



















