前端实现主题(深色模式)切换的几种方案

方案一:link 动态引入

通过改变link 标签的 href 属性实现动态修改样式(暂不推荐这种方案)

优点:实现了按需加载,提高了性能;

缺点:动态加载样式文件,可能会因为网络问题导致样式加载过慢;

           可维护性较差,后续新增或修改主题较为麻烦。

方案二:提前引入样式,类名切换

在这个方案中,我们只有一个css文件,然后通过js来改变他的类名(也暂不推荐这种方案)

优点:相比方案一,不会因为网络问题导致样式切换延迟;

缺点:样式文件过大时可能会出现首屏加载过慢问题;

           可维护性依旧较差,后续新增或修改主题较为麻烦;

方案三:CSS 滤镜

利用CSS3新增的filter属性(需求简单可以使用)

优点:一行代码实现黑色主题功能,简单易于维护;

缺点:不能满足需求的要求,不能实现对区域的主题颜色自定义;

方案四:CSS变量+类名切换(目前的主流方案)

VUE3官方文档使用的解决方案(比较推荐),这一个方案也是我目前使用的方案

实现思路:首先定义几个我们需要的全局样式变量,之后定义几个集合属性<html lang="en" data-theme="dark">(不同的主题样式),然后将其放在html根元素标签里,再动过js动态的切换这个集合属性就可以实现主题的切换,具体看以下代码;

优点:不会因为网络问题导致样式切换延迟;

           在需要切换主题的地方利用 var0绑定变量即可,不存在优先级问题;

           新增或修改主题方便灵活,仅需新增或修改 CSS 变量即可,在 var()绑定样式变量的地             方就会自动更换;

缺点:首屏加载时会牺牲一些时间加载样式资源;

预览效果

具体实现

<!DOCTYPE html>
<!-- <html lang="en" data-theme="light"> --><html lang="en" data-theme="dark">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>王国梁</title><link rel="shortcut icon" href="./img/w.png" type="image/x-icon"><!-- 引入谷歌字体 --><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><linkhref="https://fonts.googleapis.com/css2?family=Dhurjati&family=Noto+Sans+SC:wght@400;500;600;700;800;900&display=swap"rel="stylesheet"><!-- 自定义样式 --><link rel="stylesheet" href="./index.css"><style>.container {}</style>
</head><body><!-- 标题部分 --><header><a href="#" class="logo"><span>W</span>GL</a><ul class="nav-bar"><li><a href="#">首页</a></li><li><a href="#">教育背景</a></li><li><a href="#">技术栈</a></li><li><a href="#">经历</a></li><li><a href="#">博客</a></li><li><a href="#">联系我</a></li></ul><div><span>更多</span><div></div></div><button onclick="toggle()" class="toggle">切换主题</button><!-- <theme-button value="dark" id="btn" size="3"></theme-button> --></header><!-- 自定义js文件链接 --><script src="./index.js"></script>
</body></html>
*{padding: 0;margin: 0;box-sizing: border-box;font-family: "rubik",sans-serif;list-style: none;text-decoration: none;
}@media screen and (max-width: 768px) {}/* 全局样式变量 */
:root{/* 背景色/边框颜色/主色/辅色/其他色 */--color-border:#deddee;--color-main:#ffae00;--color-auxiliary:#00ff11;--color-other:#00ffdd;--color-bg:#1f1f21;--font-color-main:#ffffff;--font-color-secondary:#ffffffb3;--font-color-auxiliary:#ffffff3b;/* 字号和字体颜色 */--font-root:1rem;--font-32px:2rem;--font-20px:1.25rem;--font-18px:1.125rem;--font-16px:1rem;--font-14px:.875rem;--font-12px:.75rem;--font-10px:.625rem;/* 层级 */--z-index10:10;--z-index100:100;--z-index1000:1000;/* 间距 */--spacing-2:.125rem;--spacing-4:.25rem;--spacing-6:.375rem;--spacing-8:.5rem;--spacing-10:.625rem;--spacing-12:.75rem;--spacing-14:.875rem;--spacing-16:1rem;--spacing-20:1.25rem;--spacing-24:1.5rem;--spacing-30:1.875rem;--spacing-40:2.5rem;--spacing-50:3.125rem;--spacing-60:3.75rem;
}
/* 集合属性(主题样式) */
[data-theme="dark"] {--color-bg:#1f1f21;--color-btn:#ffffff;--color-btn-font:#333333;--color-border:#deddee;--color-main:#ffae00;--color-auxiliary:#00ff11;--color-other:#00ffdd;--font-color-main:#ffffff;--font-color-secondary:#ffffffb3;--font-color-auxiliary:#ffffff3b;
}
[data-theme="light"] {--color-bg:#ffffff;--color-btn:#000000;--color-btn-font:#ffffff;--color-border:#deddee;--color-main:#ffae00;--color-auxiliary:#00ff11;--color-other:#00ffdd;--font-color-main:#333333;--font-color-secondary:#777777;--font-color-auxiliary:#aaaaaa;
}/* 切换按钮 */
.toggle{border: none;padding: var(--spacing-6);font-size: var(--font-14px);background-color: var(--color-btn);color: var(--color-btn-font);border-radius: .25rem;transition: all ease .45s;
}body{background: var(--color-bg);color: var(--font-color-main);overflow-x: hidden;transition: all 0.5s ease-in-out;
}/* 标题部分 */
header{position: fixed;top: 0;right: 0;width: 100%;background: transparent;z-index: var(--z-index10);font-size: var(--font-14px);display: flex;align-items: center;justify-content: space-between;padding: var(--spacing-30) 15%;transition: all ease .45s;
}
.logo{color: var(--font-color-main);font-weight: 600;font-size: var(--font-32px);
}
.logo span{color: var(--color-main);    
}
.nav-bar{display: flex;
}
.nav-bar a{font-size: var(--font-14px);color: var(--font-color-secondary);margin:0 var(--spacing-24);transition: all ease.5s;
}
.nav-bar a:hover{color: var(--color-main);font-weight: 600;
}
// 切换主题
function toggle() {let html = document.querySelector('html')let currentTheme = html.getAttribute('data-theme');if (currentTheme === "light") {html.setAttribute('data-theme', 'dark');} else {html.setAttribute('data-theme', 'light');}
}

方案五:v-bind (Vue3)

在vue3中基于响应式对css变量进行动态改变

优点:不用考虑网络问题;

           在需要切换主题的地方利用 v-bind 绑定变量即可,不存在优先级问题;

           新增或修改主题方便灵活,仅需新增或修改JS 变量即可,在v-bind0绑定样式变量的地方就             会自动更换;

缺点:也是首屏加载时会牺牲一些时间加载样式资源;

           这种方式只要是在组件上绑定了动态样式的地方都会有对应的编译成哈希化的 CSS 变量,             而不像 CSS变量一样统一地在:root 上设置;

还有剩下的一些方案就不一一介绍了,感觉有用就点个赞再走吧

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/202194.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Scanner扫描器和if语句来判断QQ等级的活跃程度

一、主要特点 总体使用try包围起来&#xff0c;用到了Scanner扫描器&#xff0c;还用到了若干if语句。 二、运行代码 import java.util.Scanner; public class QQtest {public static void main(String[] args){try (Scanner scan new Scanner(System.in)) {System.out.pr…

torch 如何实现两点分布采样,100个样本中20个样本为1,80个为2

方法1 可以使用 PyTorch 中的 torch.distributions 模块实现两点分布采样。具体来说&#xff0c;可以使用 Categorical 分布将数字1和数字2的概率分别设为0.2和0.8&#xff0c;然后调用 sample() 方法进行采样。 下面是实现上述功能的代码示例&#xff1a; import torch # 创…

rename--统一的PRF

将ARF/PRF进行合并&#xff0c;合同之后的不见&#xff0c;称之为统一的PRF(Physical Register File);存储的是speculative的&#xff0c;以及正确的&#xff08;retire&#xff09;寄存器值&#xff1b;

【已解决】Qt mouseMoveEvent、mouseReleaseEvent失效无法触发

问题背景 我有一个派生自QGraphicsObject的类&#xff0c;这个类其实就是同时继承了QGraphicsItem和QObject的类 相当于在QGraphicsItem的基础上增加了事件消息的功能 我派生出来的这个类主要是实现了由多个点组成的多边形 现在想实现一个功能&#xff0c;拖动其中的某个点…

吉利护航,宣称比友商“更懂车”,魅族造车的底气与底色

继小米、华为后&#xff0c;又一家手机厂商宣布跨界造车。 在近日举办的2023魅族秋季无界生态发布会上&#xff0c;星纪魅族集团&#xff08;下称“魅族”&#xff09;董事长兼CEO沈子瑜宣布&#xff0c;魅族正式进入汽车市场&#xff0c;将在2024年第一季度启动“DreamCar共创…

promise使用示例

下面是一个 Promise 使用示例&#xff0c;通过 Promise 实现异步操作的链式调用&#xff1a; const getUser (userId) > {return new Promise((resolve, reject) > {// 模拟异步请求setTimeout(() > {const users [{ id: 1, name: Alice },{ id: 2, name: Bob },{ …

按需分发饼干

题意&#xff1a; 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这是能让孩子们满足胃口的饼干的最小尺寸&#xff1b;并且每块饼干 j&#xff0c…

ChatGPT学习笔记

1 模型训练 ChatGPT在训练时使用了PPO方法&#xff1b;

【STM32】STM32学习笔记-课程简介(01)

00. 目录 文章目录 00. 目录01. 课程简介02. 硬件设备03. 软件工具04. 硬件套件4.1 面包板和跳线/飞线4.2 杜邦线和STM32最小系统板4.3 STLINK和OLED显示屏4.4 LED和按键4.5 电位器和蜂鸣器4.6 传感器和旋转编码器4.7 USB转串口和MPU60504.8 Flash闪存和电机模块4.9 SG90舵机 0…

win10与 vm虚拟机win7共享文件夹创建

1:在win10&#xff08;主机&#xff09;电脑先随意共享一个文件夹 2&#xff1a;在win10&#xff08;主机&#xff09;上创建一个网络映射 右键此电脑选择映射网络驱动器 成功后会多出这个网络位置 3&#xff1a;win7虚拟机设置 在虚拟机中点击计算机右键添加一个网络位置

C# Onnx CenterNet目标检测

目录 效果 模型信息 项目 代码 下载 效果 模型信息 Inputs ------------------------- name&#xff1a;input.1 tensor&#xff1a;Float[1, 3, 384, 384] --------------------------------------------------------------- Outputs ------------------------- name&a…

安卓开发引入网络图片

<ImageViewandroid:id"id/img01"android:layout_width"match_parent"android:layout_height"200dp"android:layout_weight"1"/>ImageView加载网路图片 第一步&#xff1a;添加网络权限 <uses-permission android:name"…

vue使用实现录音功能js-audio-recorder

前言 最近项目中需要实现一个录音上传功能&#xff0c;用于语音评论可以上录音。 下载插件&#xff1a; npm i js-audio-recorder完整代码 <template><div style"padding: 20px;"><h3>录音上传</h3><div style"font-size:14px"…

“轻松管理视频文件:高效归类与统一重命名“

随着电子设备的普及&#xff0c;我们的视频文件可能来自各种不同的源头&#xff0c;如何高效地管理和查找这些文件成为了一个问题。今天&#xff0c;我们将为您提供一个完美的解决方案——自动归类并统一重命名视频文件。 首先&#xff0c;第一步&#xff0c;我们要进入文件批…

【Python百宝箱】优化 Python 中的科学计算与建模:从 SymPy 到 Optuna

掌握Python科学计算&#xff1a;符号运算、数值计算与模型优化 前言 本文将带您深入了解 Python 中一系列重要的科学计算与优化库。从 SymPy 提供的符号计算&#xff0c;到 scikit-optimize 的贝叶斯优化&#xff0c;再到 NumPy 和 SciPy 的数值计算和统计建模&#xff0c;以…

Unsupported class file major version xx

Java SE 和 Major Version 对应关系如下&#xff1a; Java SEMajor VersionHex18620x3E17610x3D16600x3C15590x3B14580x3A13570x3912560x3811550x3710540x369530x358520x347510x336.0500x325.0490x311.4480x301.3470x2F1.2460x2E1.1450x2D 修改对应SE和major关系可以解决如…

我一人全干!之vue3后台管理中的大屏展示。

使用大屏展示的时候有很多种场景&#xff0c;众多场景都是为了实现大屏自适应。 大屏&#xff0c;顾名思义&#xff0c;就是放在一个固定的屏幕上看的&#xff0c;即使你不做自适应&#xff0c;放在一个固定的屏幕上看也没啥问题&#xff0c;但是很多做大屏的是为了在PC端看&am…

Python中 长度判断与限制

#1.长度判断与限制 # "raise" 是一个 Python 中用于抛出异常的关键字这允许程序员在发生错误或不符合预期条件的情况下&#xff0c; # 提前终止程序的执行并给出相应的错误信息。 def ren(name: str, age: int):if len(name) > 3:raise ValueError("Name len…

【JAVA】Maven构建java-grpc-protobuf代码生成测试

本次是通过Maven工具构建Java测试工程&#xff0c;需要将原本通过gradle构建的项目需要通过maven构建加入公司代码库&#xff0c;通过Maven构建涉及到接下来要介绍的插件&#xff0c;总是发现pom.xml编译不通过&#xff0c;看到网上都是千篇一律的插件配置&#xff0c;自己就是…

MySQL 高级函数

1. MySQL 高级函数BIN(x) MySQL高级函数BIN(x)用于将一个整数转换为二进制字符串。 语法&#xff1a; BIN(x)示例&#xff1a; SELECT BIN(10);这将返回’1010’&#xff0c;表示整数10的二进制表示为1010。 2. MySQL 高级函数BINARY(s) MySQL高级函数BINARY(s)用于将字符…