前言
鉴于 Sunfire 自定义大盘夜间模式上线后好评如潮,有人问能不能直接使用,在这里,我就来一波解密吧!
首先,什么是夜间模式?
理解夜间模式
让屏幕整体的亮度和夜间环境更接近,从而减小对眼睛的刺激。
很多人以为深色风格=夜间模式,其实二者是有本质差别的。
深色风格 UI 容易承托产品的品牌特性以及氛围感。但深色 UI 并没有针对夜间情景下专门去考虑,在白天与夜间情景下都可以使用。那么夜间模式与深色风格有什么区别呢?
首先,引入尼特值(nit)。
用于量化亮度强度的专业术语,其意思每平方米烛光的强度:1nit=1 坎德拉/平方米。
白天,人的眼睛能适应亮度的值高于3.4尼特
;
夜晚,主体颜色接近0.034 尼特
,最亮元素低于3.4尼特
的亮度眼睛会比较舒适。
将尼特值换算成 HSB 颜色模式。也就是说主色调颜色(一般指背景色或最暗的颜色)的亮度不超过 20(0<B<20)
,避免使用极端颜色(纯黑),最亮的颜色亮度尽量不超过 50
。
HSB 与 HSL 的区别
对于一个前端来说,一定知道 HSL
,但不一定知道 HSB
。因为 CSS 中的 <color>
支持三种描述:
- 使用一个关键字
- 使用 RGB立体坐标(RGB cubic-coordinate)系统(以“#”加十六进制或者 rgb() 和 rgba() 函数表达式的形式)
- 使用 HSL圆柱坐标(HSL cylindrical-coordinate)系统(以 hsl() 和 hsla() 函数表达式的形式)
RGB 是对机器很友好的色彩模式,但并不够人性化,我们并不知道这个颜色是亮还是暗。HSL 模式和 HSB 都是基于 RGB 的,是作为一个更方便友好的方法创建出来的。
- HSB 为 色相,饱和度,明度;
- HSL 为 色相,饱和度,亮度;
如果你使用 HSL
直接套 HSB ,那么你得到的可能是完全不同的颜色
。
构建夜间模式
构建一个好的夜间模式需要考虑一下几个因素:
低尼特值(低亮度)
对于屏幕呈现的亮度的控制,需要通过前面提到的尼特值确定。尼特值能够反馈产品呈现亮度,它直接影响了人眼的亮度舒适程度。
主色调颜色(一般指背景色或最暗的颜色)的亮度不超过 20(0<B<20)
,避免使用极端颜色(纯黑),最亮的颜色亮度尽量不超过 50
。
我们构建夜间模式的颜色如下:
通过软件 sketch 可以看到,我们使用的背景色亮度为 7,完全符合要求。
如果你是已实现的页面,可通过 colorconvert 将 RGB 转化为 HSB 进行查看。
可以看到,背景色的信息如下:
- RGB 的十六进制(Hex)表达值:080A13
- RGB 的函数表达值:(8, 10, 19)
- HSL 的函数表达值:(229, 41, 1)
- HSB 的值:(229, 58, 7)
与在 sketch 中看到的完全匹配。
低纯度的颜色
纯度即上述提到的饱和度。
使用柔和,低纯度的色彩可以使界面看起来更舒服,增加用户的使用时长。
我们选取的颜色饱和度基本上不超过 60% 。
对比度在能看清的范围内
对比度规范是由Web 无障碍指南(WCAG)提出,现已经逐步被大公司采纳,苹果公司的设计规范中引用了此对比度规范。结合夜间模式的需求,我们提出保证文字与背景色对比度在3:1-4.5:1范围,保证元素(头像,图片)与背景色的对比度在3:1-7:1的范围内。以此保证文字的清晰度,减少其他元素过亮的情况。
颜色对比查看可通过 Contrast Ratio 查看。
对于集团监控页面我直接使用 chrome 插件测试得到:
略(涉及到阿里内部信息)
小结:有了以上基础后,便开始前端实现啦~
实现夜间模式
我们使用的方案是:如果是夜间模式,则会在body标签中添加 dark
的 class 标记以及在 url 中添加 dark
的 hash 标记。然后写好切换夜间模式
的逻辑,同时完成 dark
下的样式即可。
控制条件 hash
我们需要记住夜间模式,有多种方式。比如,保存到 state 中、保存到 localStorage 中等,但只有在url中是最优解,因为对于自定义大盘而言,用户期望接收链接方看到的就是发送时的模式。
我们会在切换模式的 dom 上绑定点击事件,当用户点击时,增加/删除 夜间模式的 dark
hash 标记,使用的是 location.hash
,并执行函数 toggleThemeDark
(下文将提到)。
变量替换 sass
首先,在样式文件中定义好颜色变量。
$axis-color: #454A78;
$card-bg: #141830;
$bg-color: #080A13;
$card-hover-color: #20264A;
...
注意:变量替换需要考虑周全
,严格把控变量名的规范性、语义性
以及考虑到 hover 样式
、table 的奇偶行
等问题。
然后,完成 CSS 样式,当所有的元素在 dark
下的呈现样式。
.dark{
/*set page style */
.plugin-config-title h3 {
color: $main-color
}
...
/* 滚动条滑块 */
::-webkit-scrollbar-thumb {
background-color: $table-even-color;
border: 3px solid $bg-color;
border-radius: 8px;
}
::-webkit-scrollbar-thumb:window-inactive {
background-color: $table-even-color;
opacity: 0.9;
}
::-webkit-scrollbar-button {
display: none;
}
::-webkit-scrollbar {
background-color: $bg-color;
width: 14px;
height: 14px;
}
::-webkit-scrollbar-track-piece {
display: none;
}
::-webkit-scrollbar-button {
display: none;
}
...
}
在这里我给出了一个简单示例以及完整的 chrome 滚动条夜间模式样式(方便朋友们 copy ),其它样式在此不一一给出。
样式容器 body
上文中提到执行的函数 toggleThemeDark
,内容如下:
export const toggleThemeDark = function (bool, topContainer = '.aisc-content') {
const needFull = document.querySelector(topContainer);
const body = document.querySelector('body');
if (bool) {
needFull.style.backgroundColor = $bgColor;
body.classList.add('dark');
} else {
body && body.classList.remove('dark');
needFull.style.backgroundColor = 'transparent';
}
}
函数参数第一个 bool 即为修改为夜间模式的真假值,获取到 body 标签, 在夜间模式下添加 dark
class,在非夜间模式则去除 dark
class。
页面便会出现不同的展现形式。
小结:实现方式可能有很多,我们选择的是满足需求投入最少工时的一种方式。
结尾
欢迎大家指正