不一定,深色模式切换不强制依赖prefers-color-scheme;它是最轻量、兼容性好且符合系统偏好的自动方案,但手动切换需结合data-theme属性与js控制,并用css变量和媒体查询协同实现。

深色模式切换必须依赖 prefers-color-scheme 吗?
不一定,但这是最轻量、最兼容、最符合用户系统偏好的方式。Less 本身不执行运行时逻辑,它只编译成 CSS,所以不能像 JavaScript 那样监听主题切换或动态修改变量。真正起作用的是编译后的 CSS 中的 @media (prefers-color-scheme: dark) 规则,Less 只负责帮你更干净地组织这些规则。
如果你需要手动切换(比如带开关的按钮),就得靠 JS 控制 class(如 html[data-theme="dark"]),这时 Less 要配合这个 class 写嵌套规则——别指望 Less 自己“感知”主题变化。
用 Less 变量 + 媒体查询写深色模式的正确姿势
别在每个选择器里重复写深色值,也别用 @import 分开维护两套变量。推荐用「变量映射 + 媒体查询包裹」的方式:
- 定义一组基础语义变量(如
@bg-primary、@text-primary),不直接赋颜色值 - 用
.theme-light和.theme-dark两个 mixin 分别设置这些变量的具体值 - 在根级用
@media (prefers-color-scheme: light)和@media (prefers-color-scheme: dark)分别调用对应 mixin - 所有组件样式写在媒体查询内部,直接引用语义变量
示例片段:
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
.theme-light() {
@bg-primary: #ffffff;
@text-primary: #333333;
}
.theme-dark() {
@bg-primary: #121212;
@text-primary: #e0e0e0;
}
@media (prefers-color-scheme: light) {
.theme-light();
body { background: @bg-primary; color: @text-primary; }
}
@media (prefers-color-scheme: dark) {
.theme-dark();
body { background: @bg-primary; color: @text-primary; }
}
手动切换主题时,Less 怎么配合 data-theme 属性?
当你要支持用户点击切换(绕过系统偏好),就得让 CSS 响应 html[data-theme="dark"] 这类属性。Less 里不能动态改变量作用域,所以得靠嵌套和 guard(条件)来生成对应规则:
- 把所有深色样式写在
html[data-theme="dark"] { ... }下,而不是媒体查询里 - 避免同时写
@media和[data-theme]两套逻辑,否则容易冲突 - 如果想共用部分变量,可用
extract()或 map 结构预定义颜色表,再用when判断 - 注意 specificity:
html[data-theme="dark"] .btn比.btn优先级高,但比.btn.dark低,别被覆盖
简单写法示例:
@colors: {
light: {
bg: #fff;
text: #333;
};
dark: {
bg: #111;
text: #eee;
};
};
html[data-theme="light"] {
--bg: extract(extract(@colors, light), bg);
--text: extract(extract(@colors, light), text);
}
html[data-theme="dark"] {
--bg: extract(extract(@colors, dark), bg);
--text: extract(extract(@colors, dark), text);
}
body { background: var(--bg); color: var(--text); }
编译后 CSS 体积和兼容性要注意什么?
Less 编译出的深色模式 CSS 会变大——尤其是你用了多层嵌套 + 两套变量。Chrome 和 Safari 对 prefers-color-scheme 支持很好,但 Firefox 直到 96+ 才完全支持,IE 完全不支持。所以:
- 若需兼容旧浏览器,必须 fallback 到
data-theme方案,且 JS 初始化时要读取matchMedia结果设初始值 - 别在 Less 里用
javascript(...)函数试图运行时计算,它只在编译期执行,无法响应切换 - 避免在 mixin 里写大量重复声明,Less 不会去重,会导致 CSS 体积膨胀
- 如果项目用 Webpack + less-loader,确认开启了
javascriptEnabled: true(仅当你真需要内联 JS 计算时),但绝大多数主题场景不需要
真正麻烦的不是怎么写 Less,而是如何让 JS 初始化逻辑和 CSS 规则对齐:比如用户刚打开页面时,CSS 还没加载完,JS 就设置了 data-theme,结果闪屏。这事 Less 解决不了,得靠 loading 策略或 SSR 注入。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










