几种实现主题切换的方式
几种实现主题切换的方式
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的博文。在还没开始写之前,我已经预见到,这恐怕将是…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...

大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...

剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...

dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...

回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...