背景跟随系统主题的变化而变化
效果如下
一、实现思路
利用媒体查询的方式
二、相应操作
1.html布局
采用 grid 布局
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>主题切换</title>
</head>
<body>
<div class="body ">
<div class="check">
<div class="light_div"><span>明亮</span></div>
<div class="dark_div"><span>暗黑</span></div>
<div class="OS_div"><span>跟随系统</span></div>
</div>
<div class="content">
<div class="table" style="grid-template-columns: auto;font-size: 20px;text-decoration: underline;"><span>王者农药</span></div>
<div class="table top"><span>角色</span><span>属性</span><span>性别</span></div>
<div class="table"><span>后裔</span><span>射手</span><span>男</span></div>
<div class="table"><span>项羽</span><span>战士</span><span>男</span></div>
<div class="table"><span>王昭君</span><span>法师</span><span>女</span></div>
</div>
</div>
</body>
</html>
2.css
主要采用 css的变量——形式如:color: var(上面定义的变量名)
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
/* 默认亮色主题 */
:root {
--bg1: hsl(144, 100%, 89%);
--bg2: hsl(42, 94%, 76%);
--underlineColor: #333;
--textColor: #333
}
/* 暗黑主题 */
/* 加了html,它的特殊性为011,而原有的html为010,根据层叠规则而生效哪一套
*/
html[data-theme='dark'] {
--bg1: hsl(198, 44%, 11%);
--bg2: hsl(198, 39%, 29%);
--underlineColor: #fff;
--textColor: #fff
}
/* css 中监听当前系统的颜色 */
/* @media (prefers-color-scheme:dark) {}
;
@media (prefers-color-scheme:light) {}
; */
.body {
width: 100%;
height: 100vh;
background-image: linear-gradient(var(--bg1), var(--bg2));
display: flex;
flex-direction: column;
justify-self: center;
align-items: center;
color: var(--textColor);
}
.body .check {
height: 26px;
margin-top: 60px;
margin-bottom: 60px;
display: grid;
grid-auto-flow: column;
grid-template-columns: repeat(3, 1fr);
grid-gap: 20px;
}
.body .content {
width: 600px;
height: 315px;
display: grid;
border: 2px solid var(--underlineColor);
}
.top {
font-weight: 700;
}
.body .content .table {
display: grid;
/* 溢出后是纵向还是横向排列 */
grid-auto-flow: column;
grid-template-columns: repeat(3, 1fr);
grid-gap: 30px;
justify-items: center;
align-items: center;
}
.light_div,
.dark_div {
border-bottom: none;
}
.light_div span:hover,
.dark_div span:hover,
.OS_div span:hover {
cursor: pointer;
border-bottom: 1px solid var(--underlineColor);
}
3.js
采用颜色聚合算法来算出图片的主要三个颜色像素
// 通过判断是否点击来确定更换主题
const match = matchMedia('(prefers-color-scheme:light)'); // 可以用来查看系统的主题颜色
if (JSON.parse(localStorage.getItem("os_check"))) {
OS_State()
match.addEventListener("change", OS_State); // 用来监听系统是否有发生变化
} else {
match.removeEventListener("change", OS_State)
document.documentElement.dataset.theme = localStorage.getItem("_theme_") || "light";
};
let light = document.querySelector(".light_div");
let dark = document.querySelector(".dark_div");
let OS = document.querySelector(".OS_div");
light.addEventListener("click", () => {
document.documentElement.dataset.theme = "light"
match.removeEventListener("change", OS_State)
localStorage.setItem("_theme_", "light")
localStorage.setItem("os_check", false)
});
dark.addEventListener("click", () => {
document.documentElement.dataset.theme = "dark"
match.removeEventListener("change", OS_State)
localStorage.setItem("_theme_", "dark")
localStorage.setItem("os_check", false)
})
OS.addEventListener("click", () => {
// console.log("点击zhuti ");
localStorage.setItem("os_check", true)
OS_State() // 点击之后要先运行
match.addEventListener("change", OS_State)
});
// 做一个判断系统主题颜色的函数
function OS_State() {
if (match.matches) {
// console.log("系统明亮");
document.documentElement.dataset.theme = "light"
localStorage.setItem("_theme_", "light")
} else {
// console.log("系统暗黑");
document.documentElement.dataset.theme = "dark"
localStorage.setItem("_theme_", "dark")
}
};