白天模式 light 和 黑夜模式 dark 实现方案
方案一
demo
原理
生成两份 css, 通过 head 引入不同文件(只能两者中的一个)
- light-mode.css
- dark-mode.css
<head> <link rel="stylesheet" type="text/css" href="light-mode.css"> </head> <head> <link rel="stylesheet" type="text/css" href="dark-mode.css"> </head>
优缺点
- 每次切换需要重新下载 css,消耗服务器资源
- 页面渲染时间 = css 资源下载时间 + 页面重绘时间
- 客户端渲染 csr + 服务端渲染 ssr 都可以实现
- 解决低版本浏览器兼容问题
- 首次下载 css 文件会比较大,可以通过缓存解决问题
方案二
生成一份 css,里面包含两种 css 样式,通过改变 body-> classname 类型
<head> <link rel="stylesheet" type="text/css" href="light-dark.css"> </head> <body classname="xxxxxxxx-light"></body> <head> <link rel="stylesheet" type="text/css" href="light-dark.css"> </head> <body classname="xxxxxxxx-dark"></body>
优缺点
- 只需要一份 css,里面包含 light&dark 样式
- 首次下载 css 文件会比较大
- 每次切换不需要重新下载 css,减少服务器的请求
- 客户端渲染 csr + 服务端渲染 ssr 都可以实现
- 解决低版本浏览器兼容问题
方案三
demo
原理
data-theme 切换
<html data-theme="light"></html> <html data-theme="dark"></html> /* 定义颜色 */ :root { --myColor: '#fff'; } /* 利用公共元素,当它匹配了特定属性时,改变变量对应色值 */ html[data-theme="dark"] { --myColor: '#000'; } /* 引用颜色 */ .myComponent { color: var(--myColor); }
优缺点
- 只需要一份 css,里面包含 light&dark 样式
- 客户端渲染 csr + 服务端渲染 ssr 都可以实现
- 速度更快,渲染时间更多
- 低版本浏览器不兼容,例如不兼容部分浏览器(IE 11 和 Android 4)
方案四
配合 less sass stylus 等样式预处理
举个:
less 的,改变样式的变量名来实现模式切换;当点击按钮切换模式时,引入修改的 css 样式(非请求远程服务器的 css 资源)
// light 下的样式 normal.css @button-bg-color: #000666; .button { background-color: button-bg-color; } // dark 变量文件夹 dark.js export default { '@checkobx-checked-disabled-bg-color': '#654321' } // 引入 <style type="text/css" id="less:static-index"> ............... *************** </style> // 代码的实现 import darkTheme from './dark.js'; window['less'] && window['less'].modifyVars(darkTheme);
优缺点
- 切换时间慢(在浏览器编译,本地 updatecss 样式,操作 dom,而不是引用服务器的 css)
- 支持 csr & ssr
- 使用 webpack less-loader 的 modifyVars 的配置方法
方案五
css 的 mix-blend-mode 反色效果, 修改 ‘background-color’。(效果不太好)
<body> <div><!-- 一个紧跟在 body 之后的空的 div --></div> <!-- 这里开始是页面的主要内容 --> </body> div { position: fixed; top: 0; left: 0; right: 0; bottom: 0; /* fixed 定位覆盖页面 */ z-index: 9999; /* 层叠放到很高的一个位置,盖在页面上 */ mix-blend-mode: difference; /* 混合模式,反色 */ background-color: #fff; /* 结合混合模式做反色处理的对比色 */ pointer-events: none; /* 作为一个层覆盖在元素上,但不能妨碍页面元素点击,添加一个穿透效果 */ }
优缺点
方案六
实现原理:媒体查询;media + prefers-color-scheme
@media screen and (prefers-color-scheme: dark) { /* 在这里把需要转换的样式样式加上就好了 */ } body { color: #333; /* 在 light mode 时,页面中的文字颜色 */ } @media screen and (prefers-color-scheme: dark) { body { color: #fff; /* 如果系统切换到 dark mode 时,页面中的文字颜色改变 */ } } // @media 引入方式 <link href="./dark-mode_test/md.css"> <link href="./dark-mode_test/md-dark-mode.css" media="(prefers-color-scheme: dark)"></link> @import url('./md-dark-mode.css') (prefers-color-scheme: dark);
总结
dark mode 要在网页中实现,首先就是要考虑浏览器的兼容性问题,关键是是否支持 CSS 自定义属性,至于 prefers-color-scheme 不支持的话,那也不用谈 dark mode 了,只要 CSS 自定义属性兼容,就可以相对减少一点体力活。
其次,dark mode 时,页面中的图片需要怎么处理时需要考虑的。直接加滤镜或者透明度,还是换一套图。
最后,如果要把以前的页面都去做这个 dark mode 必然会消耗很多时间,排查颜色相关的属性,重新设计在 dark mode 下的颜色,图片是否替换。
最后的最后,个人感受,既然这个是一个新的玩法,或许可以考虑在新的项目中考虑去实现,如果是把之前的页面都重新整一遍,总感觉付出和收获是不成正比的。
延伸阅读:
暂无内容!
评论列表 (0条):
加载更多评论 Loading...