白天模式 light 和 黑夜模式 dark 实现方案

 2个月前     2  

文章目录

方案一

demo

https://rsuitejs.com/

原理

生成两份 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

https://redux.js.org/

原理

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 下的颜色,图片是否替换。

最后的最后,个人感受,既然这个是一个新的玩法,或许可以考虑在新的项目中考虑去实现,如果是把之前的页面都重新整一遍,总感觉付出和收获是不成正比的。

暂无评论

暂无评论...