利用css变量实现切换主题的几种方式
这么久就写了一篇文章,今天休假,趁着两个儿子睡着啦来讲讲怎样利用css实现主题的切换。 css变量语法如下,更多css用法参考mdn的 Using_CSS_custom_properties:
/* 定义方式1 */
:root{
--body: rgba(0,0,0,0.88);
}
/* 定义方式2 */
[data-theme="light"]{
--body: rgba(0,0,0,0.88);
}
实现方式1
一种就是不考虑提供自定义主题,我们设置固定的几套由UI精心设计的主题,相对的css代码会多一些,用户不需要考虑那么多,直接简单切换喜欢的主题。
下面是代码示例:
<!DOCTYPE html>
<!-- 默认主题是在这里设置data-theme属性 -->
<html lang="zh" data-theme="dark">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>样式设置</title>
<style>
/* 定义深色主题 */
[data-theme="dark"] {
--body: rgba(0, 0, 0, 0.88);
--color: rgba(255, 255, 255, 0.88);
}
/* 定义亮色主题 */
[data-theme="light"] {
--body: rgba(255, 255, 255, 0.88);
--color: rgba(0, 0, 0, 0.88);
}
body {
/* 用变量设置界面背景颜色 */
background-color: var(--body);
/* 用变量设置文字颜色 */
color: var(--color);
margin: 0;
height: 100vh;
display: grid;
align-content: center;
justify-items: center;
}
#theme-toggle{
cursor: pointer;
}
</style>
</head>
<body>
<div>
<div>
<!-- 主题切换 -->
<div id="theme-toggle">
<!-- 太阳图标 -->
<svg id="sun" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-sun"><circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22" ></line></svg>
<!-- 月亮 -->
<svg id="moon" style="display: none;" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-moon"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>
</div>
</div>
</div>
<script>
const themeToggle = document.getElementById("theme-toggle");
const moonPath = document.getElementById("moon");
const sunPath = document.getElementById("sun");
// 为主题切换div添加点击事件
themeToggle.addEventListener("click", () => {
if (!isDark()) {
// 隐藏月亮图标
moonPath.style.display = "none";
// 显示太阳图标
sunPath.style.display = "block";
// 设置主题为暗色
document.documentElement.setAttribute("data-theme", "dark");
} else {
// 显示月亮图标
moonPath.style.display = "block";
// 隐藏太阳图标
sunPath.style.display = "none";
// 设置主题为亮色
document.documentElement.setAttribute("data-theme", "light");
}
});
// 判断是否为暗色主题
function isDark() {
return "dark"==document.documentElement.getAttribute("data-theme")
}
</script>
</body>
</html>
实现方式2
另一种思路是html中只定义一套默认变量,然后界面提供主题选择利用javascript进行变量的替换,将替换后的变量标识记录到浏览器的localStorage中,重新进入页面时读取localStorage进行默认切换,后续如有自定义主题的需求也方便扩展,可以利用后端存储主题变量,加载页面时读取列表供用户进行切换及自定义主题。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>样式设置</title>
<style>
/* 定义默认变量 */
:root {
--body: rgba(0, 0, 0, 0.88);
--color: rgba(255, 255, 255, 0.88);
}
body {
/* 用变量设置界面背景颜色 */
background-color: var(--body);
/* 用变量设置文字颜色 */
color: var(--color);
margin: 0;
height: 100vh;
display: grid;
align-content: center;
justify-items: center;
}
.click{
cursor: pointer;
}
</style>
</head>
<body>
<div>
<div>
<!-- 太阳图标 -->
<svg class="click" id="sun" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-sun"><circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22" ></line></svg>
<!-- 月亮 -->
<svg class="click" id="moon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-moon"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>
</div>
</div>
<script>
const moonPath = document.getElementById("moon");
const sunPath = document.getElementById("sun");
// 为月亮图标添加点击事件,切换到暗色
moonPath.addEventListener("click", () => {
switchTheme("dark")
});
// 为太阳图标添加点击事件,切换到亮色
sunPath.addEventListener("click", () => {
switchTheme("light")
});
// 支持切换的样式缓存map
const themeMap ={
dark: {
'--body':'rgba(0, 0, 0, 0.88)',
'--color':'rgba(255, 255, 255, 0.88)',
},
light: {
'--body':'rgba(255, 255, 255, 0.88)',
'--color':'rgba(0,0,0, 0.88)',
}
}
// 执行切换样式的函数
function switchTheme(theme) {
const root = document.querySelector(':root');
// 获取需要切换的样式对象
const themePropertys = themeMap[theme];
// 获取所用对象key
const keys = Object.keys(themePropertys);
if(keys.length>0){
// 循环变更变量属性值
for (let index = 0; index < keys.length; index++) {
const propertyKey = keys[index];
root.style.setProperty(propertyKey, themePropertys[propertyKey]);
}
}
}
</script>
</body>
</html>
好了,娃儿在哭了,我要去带娃,你们去试试吧
原文始发于微信公众号(海之领域):利用css变量实现切换主题的几种方式
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/245671.html