avatar

目录
前端暗黑模式

多主题需求

自从macOS中的暗黑模式出现以后,各个应用的多主题需求也渐渐出现,本来主要讨论几种多主题的实现方案。


传统模式

传统的多主题切换依赖的是JavaScript的动态改变dom的能力,改变样式标签的href属性,来让页面加载不同的样式文件,从而达到多主题切换的目的。

我们还可以给body添加过渡效果

css
1
2
3
body {
transition: color 0.5s ease, background-color 0.5s ease;
}

示例:通过监听按钮的点击,动态改变样式标签的href

html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link id="theme_css" type="text/css" rel="stylesheet" href="./white.css" />
</head>

<body>
<h1>关于网页的主题样式</h1>

<p>
上面这个案例和以往提供的案例有所不同。该案例按前面所讲的分成三个独立的样式文件:
style.css、dark.css和light.css。尝试切换暗黑模式并重新加载页面,你会发现不匹配的样式文件仍然会被加载,只是优先级有所差异,这样做它们就不会与站点当前所需的资源竞争。
</p>

<h3>这是一个小标题</h3>

<p>
上面这个案例和以往提供的案例有所不同。该案例按前面所讲的分成三个独立的样式文件:
style.css、dark.css和light.css。尝试切换暗黑模式并重新加载页面,你会发现不匹配的样式文件仍然会被加载,只是优先级有所差异,这样做它们就不会与站点当前所需的资源竞争。
</p>

<hr>

<button onclick="handleClick()">切换主题</button>

<script type="text/javascript">
let isWhite = true
const handleClick = () => {
if (isWhite) {
isWhite = false
document.getElementById('theme_css').href = './black.css'
} else {
isWhite = true
document.getElementById('theme_css').href = './white.css'
}
}
</script>
</body>

</html>

tMfnqx.gif

CSS媒体查询

现在,可以用CSS的媒体查询prefers-color-scheme,判断用户当前的所选的主题,从而应用相应的样式

prefers-color-scheme: light 用于匹配亮白模式,prefers-color-scheme: dark 用于匹配暗黑模式

css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@media (prefers-color-scheme: light) {
h1, p {
color: black;
}

h3 {
color: blue;
}

html, body {
width: 100%;
height: 100%;
background-color: white;
}
}

@media (prefers-color-scheme: dark) {
h1, p {
color: white;
}

h3 {
color: yellow;
}

html, body {
width: 100%;
height: 100%;
background-color: black;
}
}

tloORf.gif

还可以利用JavaScript检测当前环境是否支持暗黑模式,当检测支持的时候再加载暗黑模式的样式文件,从而可以避免不支持的用户加载无用的样式文件

javascript
1
2
3
if (window.matchMedia('(prefers-color-scheme)').media !== 'not all') {
console.log('浏览器支持dark模式!(^_^)');
}


CSS Hack

此外,如果对细节要求不高,可以用简单的滤镜或者混合模式做统一处理,1秒变暗黑模式

filter

图片再加filter是让图片的色彩恢复正常

css
1
2
3
4
5
6
7
.theme-dark { 
filter: invert(100) hue-rotate(180deg);
}

.theme-dark img {
filter: invert(100) hue-rotate(180deg);
}

tlq6Cn.png

混合模式 mix-blend-mode

混合模式可以用isolate属性,设置某些元素不收混合模式的影响

css
1
2
3
4
5
6
7
8
9
.dark-mode-screen { 
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
left: 0;
background: white;
mix-blend-mode: difference;
}

tlq7CR.png

文章作者: 盛顺炎
文章链接: https://www.shengshunyan.xyz/2020/05/30/%E5%89%8D%E7%AB%AF%E6%9A%97%E9%BB%91%E6%A8%A1%E5%BC%8F/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 果实的技术分享
打赏
  • 微信
    微信
  • 支付寶
    支付寶

评论