几种实现主题切换的方式
几种实现主题切换的方式
1. 利用 prefers-color-scheme 特性
prefers-color-scheme是CSS 媒体特性【@media】用于检测用户是否有将操作系统的主题色设置为亮色【light】或者暗色【dark】。
当前prefers-color-scheme新特性支持各大主流电脑(window和IOS系统,Linux系统可以用第三方工具)端浏览器谷歌、火狐等,包括手机端的安卓和苹果,足以说明prefers-color-scheme属性已经稳定成熟,可以用于生产环境了。
prefers-color-scheme的使用也很简单,直接需要在全局css文件中添加以下代码
:root {color-scheme: light dark;
}

js可以通过window.matchMedia()来监听系统主题。
const scheme = window.matchMedia("(prefers-color-scheme: dark)");
if (scheme.matches) {console.log("深色模式");
} else {console.log("浅色模式");
}
除了自动跟随系统外,也可以手动切换。不过需要结合css变量,详情请看第四点。
优点:
- 简单
缺点:
- 不能自定义深浅主题样式
2. 切换 link
通过改变link的href。

优点
- 按需加载
缺点
- 动态加载样式,样式文件过大或者网络较慢的情况下会导致样式切换不流畅
- 存在样式优先级问题
- 后续新增样式或者修改比较麻烦
3. 引入所有主题样式,通过类名切换
类似第二种,不过为了解决反复加载样式文件问题采用提前将样式全部引入的方式,在需要切换主题的时候将指定的根元素类名更换,相当于直接做了样式覆盖,在该类名下的各个样式就统一地更换了
.light-scheme {background: #fff;
}
.dark-scheme {background: #1b1b1b;
}
function change(scheme) {const content = document.getElementsByTagName("body")[0];content.setAttribute("class", scheme);
}
优点:
- 不用重新加载样式文件,切换时不会卡顿
缺点:
- 文件较大会导致首屏加载慢
- 存在优先级问题
- 后续新增样式或者修改比较麻烦
4. css 变量 + 类名切换
大体思路跟方案 2 相似,依然是提前将样式文件载入,切换时将指定的根元素类名更换。不过这里相对灵活的是,默认在根作用域下定义好 CSS 变量,只需要在不同的主题下更改 CSS 变量对应的取值即可。
:root {--color-background: #1b1b1b;--color-text-default: #0b1016;--white-color-background: #fff;
}
.light-scheme {background: var(--white-color-background);color: var(--color-text-default);
}
.dark-scheme {background: var(--color-background);color: white;
}
let flag = true;
const content = document.getElementsByTagName("body")[0];
const but = document.getElementsByTagName("button")[0];
but.onclick = function () {flag = !flag;if (flag) {content.setAttribute("class", "light-scheme");} else {content.setAttribute("class", "dark-scheme");}
};
优点:
- 不用重新加载样式文件,在样式切换时不会有卡顿
- 在需要切换主题的地方利用
var()绑定变量即可,不存在优先级问题 - 新增或修改主题方便灵活,仅需新增或修改
CSS变量即可,在var()绑定样式变量的地方就会自动更换
缺点:
- 首屏加载时会牺牲一些时间加载样式资源

前面提到css变量还可以结合prefers-color-scheme一起使用实现跟随系统的自定义深浅主题样式。
:root {--color-background: #1b1b1b;--color-text-default: #0b1016;--white-color-background: #fff;
}
/* 监听操作系统主题模式 */
@media (prefers-color-scheme: dark) {body {background-color: var(--color-background);}
}
@media (prefers-color-scheme: light) {body {background-color: var(--white-color-background);}
}
5. css 变量 + 动态 setProperty
适合自定义颜色背景
只需在全局中设置好预设的全局 CSS 变量样式,无需单独为每一个主题类名下重新设定 CSS 变量值,因为主题是由用户动态决定。
定义一个工具类方法,用于修改指定的 CSS 变量值,调用的是 CSSStyleDeclaration.setProperty
export const setCssVar = (prop: string,val: any,dom = document.documentElement
) => {dom.style.setProperty(prop, val);
};
在样式发生改变时调用此方法即可
setCssVar("--theme-color", color);
优点:
- 不用重新加载样式文件,在样式切换时不会有卡顿
- 仔细琢磨可以发现其原理跟方案 5 利用
Vue3的新特性v-bind是一致的,只不过此方案只在:root上动态更改CSS变量而Vue3中会将CSS变量绑定到任何依赖该变量的节点上。 - 需要切换主题的地方只用在
:root上动态更改CSS变量值即可,不存在优先级问题 - 新增或修改主题方便灵活
缺点:
- 首屏加载时会牺牲一些时间加载样式资源(相对于前几种预设好的主题,这种方式的样式定义在首屏加载基本可以忽略不计)
6. vue3 专属的 v-bind
<script setup>// 这里可以是原始对象值,也可以是ref()或reactive()包裹的值,根据具体需求而定const theme = {color: "red",};
</script><template><p>hello</p>
</template><style scoped>p {color: v-bind("theme.color");}
</style>
Vue3 中在 style 样式通过 v-bind()绑定变量的原理其实就是给元素绑定 CSS 变量,在绑定的数据更新时调用 CSSStyleDeclaration.setProperty 更新 CSS 变量值。
相关文章:
几种实现主题切换的方式
几种实现主题切换的方式 1. 利用 prefers-color-scheme 特性 prefers-color-scheme是CSS 媒体特性【media】用于检测用户是否有将操作系统的主题色设置为亮色【light】或者暗色【dark】。 当前prefers-color-scheme新特性支持各大主流电脑(window和IOS系统&#…...
Jenkins使用(代码拉取->编译构建->部署上线)
Jenkins简介 Jenkins是一个开源项目,提供了一种易于使用的持续集成系统,使开发者从繁杂的集成中解脱出来,专注于更重要的业务逻辑实现上。同时Jenkins能实时监控集成中存在的错误,提供详细的日志文件和提醒功能,还能用…...
IEEE期刊论文投稿前期准备
目录 1、简介 2、资料准备 TPAMI 投稿须知 Letex模板资料下载 下载参考文献Bib文件...
[AAAI 2022] TransFG: A Transformer Architecture for Fine-grained Recognition
Contents TransFG ArchitectureExperimentsReferencesTransFG Architecture Overlapping patch split:ViT 是把图片分成一系列不重叠的 patches,作者认为这可能会破坏 discriminative regions. 为了解决上述问题,作者提出使用 Overlapping patch split,划分的 patch 数 N …...
机器学习之决策树原理详解、公式推导(手推)、面试问题、简单实例(python实现,sklearn调包)
目录1. 决策树原理1.1. 特性1.2. 思路1.3. 概念决策树概念信息论2. 公式推导2.1. 构造决策树2.1.1. ID3理论示例缺点2.1.2. C4.5理论示例缺点2.1.3. CART示例对比分析2.2. 剪枝3. 实例3.1. 数据集3.2. ID33.3. C4.53.4. CART3.5. sklearn实现4. 几个注意点(面试问题)5. 运行&am…...
一文搞懂CAS实现原理——怀玉
点个关注,必回关 文章目录CAS原理剖析1、参数解密CAS底层指令CAS(Compare and swap)是一种用于在多线程环境下实现同步功能的机制CAS原理剖析 CAS 被认为是一种乐观锁,有乐观锁,相对应的是悲观锁。 在上述示例中&…...
typora每次复制文档都要附带图片文件夹?学会配置gitee图床
0. 引言 作为开发人员,我们习惯使用md格式来编写文档,特别是typora编辑器更是日常使用的软件。但作为轻量化的文档编辑器,我们在默认插入图片时,一般typora会将图片保存到本地或者引用一个本地图片的路径 当文档还在我们本地打开…...
Linux--gdb
gdb用于实现在linux下通过gdb进行调试。由于gcc、g生成的文件是release文件,而不是用于调试的debug文件,所以需要使用gcc -g命令,生成debug文件 调试器:核心工作,主要是为了定位问题 所有查看内容的指令,不…...
c++11 标准模板(STL)(std::multimap)(二)
定义于头文件 <map> template< class Key, class T, class Compare std::less<Key>, class Allocator std::allocator<std::pair<const Key, T> > > class multimap;(1)namespace pmr { template <class Key, class T…...
【数据结构】二叉排序树——平衡二叉树的调整
文章目录前置概念一、构造平衡二叉树的基本思想二、一个示例三、平衡二叉树的调整细节(1)LL型(顺时针 )举例(2)RR型(逆时针)(3)LR型(先逆时针再顺…...
03- pandas 数据库可视化 (数据库)
pandas库的亮点: 一个快速、高效的DataFrame对象,用于数据操作和综合索引;用于在内存数据结构和不同格式之间读写数据的工具:CSV和文本文件、Microsoft Excel、SQL数据库和快速HDF 5格式;智能数据对齐和丢失数据的综合处理&#…...
第三方电容笔怎么样?开学适合买的电容笔
随着科学技术的进步,很多新型的电子产品和数码设备都出现了。比如手机,IPAD,蓝牙耳机,电容笔等等。实际上,如果你想要更好的使用ipad,那么你就需要一支电容笔。比如ipad,我们用ipad来做笔记&…...
Java学习-IO流-字节输出流
Java学习-IO流-IO流的体系和字节输出流基本用法 //IO流 → 字节流 → 字节输入流:InputStream // ↘ ↘ 字节输出流:OutputStream // ↘ 字符流 → 字符输入流:Reader // ↘ 字符输出流:WriterFileInputStream…...
linux性能分析 性能之巅学习笔记和内容摘录
本文只是在阅读《性能之巅》的过程中,对一些觉得有用的地方进行的总结和摘录,并附加一些方便理解的材料,完整内容还请阅读Gregg的大作 概念和方法 性能分析领域一词的全栈代表了整个操作系统的软硬件在内的所有事物 软件生命周期和性能规划…...
机器学习笔记之生成模型综述(三)生成模型的表示、推断、学习任务
机器学习笔记之生成模型综述——表示、推断、学习任务引言生成模型的表示任务从形状的角度观察生成模型的表示任务从概率分布的角度观察生成模型的表示任务生成模型的推断任务生成模型的学习任务引言 上一节介绍了从监督学习、无监督学习任务的角度介绍了经典模型。本节将从表…...
第八章 Flink集成Iceberg的DataStreamAPI、TableSQLAPI详解
1、概述 目前Flink支持使用DataStream API 和SQL API方式实时读取和写入Iceberg表,建议使用SQL API方式实时读取和写入Iceberg表。 Iceberg支持的Flink版本为1.11.x版本以上,以下为版本匹配关系: Flink版本Iceberg版本备注Flink1.11.XI…...
PyTorch学习笔记:nn.Sigmoid——Sigmoid激活函数
PyTorch学习笔记:nn.Sigmoid——Sigmoid激活函数 torch.nn.Sigmoid()功能:逐元素应用Sigmoid函数对数据进行激活,将元素归一化到区间(0,1)内 函数方程: Sigmoid(x)σ(x)11e−xSigmoid(x)\sigma(x)\frac1{1e^{-x}} Sigmoid(x)σ(…...
个人学习系列 - 解决拦截器操作请求参数后台无法获取
由于项目需要使用拦截器对请求参数进行操作,可是请求流只能操作一次,导致后面方法不能再获取流了。 新建SpringBoot项目 1. 新建拦截器WebConfig.java /*** date: 2023/2/6 11:21* author: zhouzhaodong* description:*/ Configuration public class W…...
【编程基础之Python】2、安装Python环境
【编程基础之Python】2、安装Python环境安装Python环境在Windows上安装Python验证Python运行环境在Linux上安装Python验证Python运行环境总结安装Python环境 所谓“工欲善其事,必先利其器”。在学习Python之前需要先搭建Python的运行环境。由于Python是跨平台的&am…...
Java开发 - 问君能有几多愁,Spring Boot瞅一瞅。
前言 首先在这里恭祝大家新年快乐,兔年大吉。本来是想在年前发布这篇博文的,奈何过年期间走街串巷,实在无心学术,所以不得不放在近日写下这篇Spring Boot的博文。在还没开始写之前,我已经预见到,这恐怕将是…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...
解析两阶段提交与三阶段提交的核心差异及MySQL实现方案
引言 在分布式系统的事务处理中,如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议(2PC)通过准备阶段与提交阶段的协调机制,以同步决策模式确保事务原子性。其改进版本三阶段提交协议(3PC…...
leetcode_69.x的平方根
题目如下 : 看到题 ,我们最原始的想法就是暴力解决: for(long long i 0;i<INT_MAX;i){if(i*ix){return i;}else if((i*i>x)&&((i-1)*(i-1)<x)){return i-1;}}我们直接开始遍历,我们是整数的平方根,所以我们分两…...
算法刷题-回溯
今天给大家分享的还是一道关于dfs回溯的问题,对于这类问题大家还是要多刷和总结,总体难度还是偏大。 对于回溯问题有几个关键点: 1.首先对于这类回溯可以节点可以随机选择的问题,要做mian函数中循环调用dfs(i&#x…...
