根本原因是颜色值被当成了字符串而非真实颜色类型:$colors 中带引号的 "#ef4444" 编译后生成非法 css,导致 background-color 无效;须用无引号颜色字面量。

为什么 @each 遍历 $colors 生成的 .bg-red 类没效果
根本原因是颜色值被当成了字符串而非真实颜色类型。Sass 编译时若把 "#ef4444" 这种带引号的写法直接塞进 background-color,会报错或静默失败——它不是合法的颜色值,无法参与渲染或后续计算。
必须确保 map 中的值是未加引号的颜色字面量:
-
$colors: ("red": #ef4444, "blue": #3b82f6);✅ 正确 -
$colors: ("red": "#ef4444", "blue": "#3b82f6");❌ 错误,编译后变成字符串,background-color: "#ef4444"是非法 CSS
检查浏览器开发者工具里对应类的 computed 样式,如果 background-color 显示为 invalid 或空白,基本就是这个原因。
生成主题类时 map-get($theme-map, text) 返回 null 怎么办
这通常不是键名拼错,而是 $theme-map 在当前作用域不可访问。Sass 的 @each 循环内部不自动继承外层变量作用域,尤其当你把遍历逻辑写在顶层、没用 @mixin 封装时,$theme-map 在选择器块里根本不存在。
正确做法是用 @mixin 把样式逻辑包起来,并显式传入 map:
- 别这么写(失效):
@each $theme, $map in $themes { .#{$theme} { color: map-get($map, text); } } - 要这么写(有效):
@mixin theme-styles($vars) { color: map-get($vars, text); } @each $theme, $map in $themes { .#{$theme} { @include theme-styles($map); } }
否则 Sass 会报 Undefined variable "$map",哪怕你在上一行刚定义了它。
JS 切换 data-theme="dark" 但样式没变
90% 是三端命名不一致:Sass 编译出的选择器、HTML 元素上的属性、JS 设置的目标值,只要有一处对不上,就完全不匹配。
比如 Sass 写的是::root[data-theme="#{$theme}"] { --text-color: #{map-get($map, text)}; },那 JS 必须严格调用:
-
document.documentElement.setAttribute('data-theme', 'dark');✅ -
document.body.setAttribute('data-theme', 'dark');❌ body 上设无效,:root 才是根元素 -
document.documentElement.className = 'dark';❌ 这是在改 class,不是 data-theme 属性
打开开发者工具,选中 元素,看 data-theme 属性值是否和你 Sass 里 @each 生成的字符串完全一致(包括大小写、有无空格)。
新增主题色后,.text-custom-blue 类没生成
Bootstrap 或自定义主题引擎默认只处理内置 key(如 primary、success),不会自动为新 key 输出工具类。即使你改了 $theme-colors,也得显式触发生成逻辑。
以 Bootstrap 为例,必须在导入完 utilities 后补上:
@import "bootstrap/scss/utilities";-
@include theme-colors();✅ 关键一步,它会遍历整个$theme-colors并输出所有.text-*、.bg-*类
漏掉这句,新增的 custom-blue 就只是 map 里的一个键,不会变成任何 CSS 类。
真正容易被忽略的是:Sass 的 @each 和 map-get 都发生在编译期,它们不感知运行时。所谓“动态”,全靠提前生成好所有主题的 CSS 规则,再靠 JS 切换 data-theme 属性来激活其中一组。一旦编译完成,CSS 文件里就只有纯规则,没有 map、没有循环、也没有变量。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











