先看个效果
默认模式:
护眼模式:
对于需要长时间盯着屏幕同学,后面这个“护眼模式”相对“默认模式”的亮底,应该算是更舒适、不那么容易引起视觉疲劳的一个选择。
在当下,作为Web前端开发者,要在网页上添加这么个护眼模式,其实可能并不需要定制化的去针对暗色调写一套完整皮肤样式。
最简单的护眼实现代码
要在任意网站启用上图的“护眼模式”,其实你只需要打开浏览器控制台,执行以下代码就可以了:
- const cssEl = document.createElement('style')
- cssEl.innerHTML = `
- html.cye-enabled {
- filter: contrast(0.96) brightness(0.9) invert(1);
- }
- html.cye-enabled img {
- filter: brightness(0.9) invert(1);
- }
- `;
- document.head.appendChild(cssEl);
- document.documentElement.classList.add('cye-enabled');
processing
很简单对不对。
其实就是给 documentElement 添加一个样式类,相应的,也就是添加个反色滤镜(让亮色变成暗色)。
不想让img图片变成反色而导致肉眼无法识别,则可以再通过滤镜反转回来。
让是否开启“护眼模式”可控
配合离线存储,记住用户设置
支持微调亮度对比度(修改文档流上下文的CSS规则)
如何监听系统主题色调变化
不带UI的,“完整”效果代码
可以复制以下代码到浏览器控制台执行,然后通过 window.setCyeFilter(enabled, contrast, brightness)
设置护眼模式开关方式、对比度、亮度。
- (() => {
- const cssEl = document.createElement('style')
- cssEl.innerHTML = `
- html.cye-enabled {
- background: #fff; /* 如果有自己的背景色,那么去掉这行 */
- filter: contrast(0.96) brightness(0.9) invert(1);
- }
- html.cye-enabled img {
- filter: brightness(0.9) invert(1);
- }
- html.cye-enabled body {
- filter: none !important; /* 防止三方浏览器插件等重复的护眼样式生效 */
- }
- `;
- document.head.appendChild(cssEl);
- // document.documentElement.classList.add('cye-enabled');
- /***** 一些JS设置逻辑 ****/
- // 护眼模式
- const getLV = (k) => JSON.parse(localStorage.getItem(k));
- const setLV = (k, v) => localStorage.setItem(k, JSON.stringify(v));
- let cyeMediaQueryList = null;
- try {
- cyeMediaQueryList = window.matchMedia('(prefers-color-scheme: dark)');
- cyeMediaQueryList.addListener(setDocCyeByLS); // 通过浏览器API监听系统层面的主题模式配置变换
- } catch(e) {
- console.warn('当前环境可能不支持 matchMedia');
- }
- window.setCyeFilter = (enabled, contrast, brightness) => {
- setLV('cyeEnabled', enabled); // true 开启护眼模式,false 关闭护眼模式,2 跟随系统主题是否黑暗模式动态设定
- setLV('cyeContrast', contrast); // 对比度,可微调视觉效果
- setLV('cyeBrightness', brightness); // 亮度,可微调视觉效果
- // 护眼模式为“开启”或“跟随系统”且系统是开启的
- const isOpen = enabled === true || (enabled == 2 && cyeMediaQueryList && cyeMediaQueryList.matches);
- const { classList } = document.documentElement || {};
- classList && classList[isOpen ? 'add' : 'remove']('cye-enabled');
- if (!isOpen) return;
- const sss = document.styleSheets;
- if (!sss) return;
- let csss = null;
- for (let i = 0; i < sss.length; i++) {
- const cssi = sss[i];
- if (cssi && cssi.ownerNode && cssi.ownerNode.id == 'ghdef') {
- csss = cssi;
- break;
- }
- }
- if (!csss) return;
- const ruls = csss.rules;
- if (!ruls) return;
- let clsObj = null;
- for (let j = 0; j < ruls.length; j++) {
- const rulj = ruls[j];
- if (rulj && rulj.selectorText === 'html.cye-enabled') {
- clsObj = rulj;
- break;
- }
- }
- if (!clsObj) return;
- clsObj.style.filter = 'contrast(' + contrast + ') brightness(' + brightness + ') invert(1)';
- return true;
- };
- // 根据本地存储,判断是否开启护眼模式
- function setDocCyeByLS() {
- setCyeFilter(
- getLV('cyeEnabled'),
- getLV('cyeContrast') || 0.96,
- getLV('cyeBrightness') || 0.9
- );
- };
- setDocCyeByLS();
- })()
scheme
CSS中的其他可用方案
mix-blend-mode: difference
https://blog.csdn.net/weixin_44733660/article/details/121958062
Comments
可以发邮件 huzunjie@pyzy.net 或移步到 https://github.com/huzunjie/blog.pyzy.net/issues 评论交流。