scss混合器无法动态读取css变量,必须通过@each遍历$theme-map生成[data-theme]选择器规则,并配合@media (prefers-color-scheme)声明变量,同时必填fallback值以保障ssr、js禁用等场景下的主题可用性。

mixins里不能直接读取CSS变量值
SCSS编译时根本看不到--text-color这类运行时才存在的CSS变量,map-get($theme-map, text)只能从SCSS的$themes map里取值。所以混合器里写的color: themed(text),本质是把预设颜色编译进CSS,不是“读取”浏览器当前变量。常见错误是以为@function themed($key)能动态响应data-theme切换——它只在构建时执行一次。
必须用[data-theme]生成选择器块
靠@each遍历$themes map,生成[data-theme="light"] .btn和[data-theme="dark"] .btn两套规则,才是运行时切换的底层支撑。要点包括:
-
$theme-map: $theme-map !global必须加,否则themed()函数拿不到当前循环的主题数据 -
&要保留父选择器上下文,比如在.card里@include background_color(background_color1),才能正确产出[data-theme="dark"] .card { background-color: #000; } - 不要写
:root[data-theme="dark"]去覆盖CSS变量——这会破坏var(--x)的继承链,且无法批量控制组件内联样式
深色模式混合器要兼容prefers-color-scheme
系统级自动适配不能只靠data-theme,得补上媒体查询。SCSS里要显式写出两套@media块:
-
@media (prefers-color-scheme: light)里定义:root所有基础变量,比如--bg-color: #fff -
@media (prefers-color-scheme: dark)里**完整重写全部变量**,漏一个就会回退到初始值或透明 - 如果项目同时支持
data-theme手动切换和系统偏好,两套逻辑要并存,不能互相覆盖 - 注意iOS Safari对
no-preference支持弱,真机测试比DevTools模拟更可靠
fallback值不是可选项,是必填项
所有var(--x, #fff)里的fallback必须写,原因很实际:
- 服务端渲染(SSR)首屏时,JS还没执行,
data-theme属性为空,var(--bg-color)会取不到值 - 用户禁用JS,或网络中断导致主题JS未加载,fallback就是最后防线
- 某些构建工具(如PostCSS插件)会移除未使用的CSS变量,导致
var(--x)直接失效 - fallback颜色应与light主题一致,避免深色模式开启瞬间闪白
:root变量声明,SCSS混合器只是帮你避免手写重复代码的工具。最容易被忽略的是:@media (prefers-color-scheme: dark)块必须和[data-theme="dark"]规则共存,且变量名、key结构必须完全一致,否则JS切换data-theme时,CSS变量值根本不会变。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











