纯CSS一分钟让网站拥有暗黑模式切换功能

news/2024/5/20 21:21:02/文章来源:https://blog.csdn.net/SOHU_TECH/article/details/109665020

本文字数:6784

预计阅读时间:17分钟

前言

暗黑模式这个概念最早起源于MacOS系统Mojave,提供浅色主题深色主题两种皮肤供用户选择,深色主题就是我们常说的暗黑模式。为了眼睛健康,笔者在手机、平板和电脑上都选择了暗黑模式

主题皮肤

随着苹果官方逐渐要求各大系统平台都得适配暗黑模式,所以笔者也探索出一种应该是市面上最低成本网站暗黑模式适配方案

很多同学可能觉得这个方案只能使用JS实现,其实可使用纯CSS实现。

思路

思路很简单,使用一个按钮来回切换主题样式。按钮未选中则切换到浅色主题,按钮选中则切换到深色主题。可用:checked和+/~打辅助完成这个任务。

  • :checked:选项选中的表单元素

  • +:元素相邻的同胞元素

  • ~:元素后面的同胞元素

使用<input>模拟按钮,当按钮处于选中状态时触发:checked,通过+/~带动后面相邻的网站主体<div>进入暗黑模式,选中状态取消时则退出暗黑模式。

<body><input class="ios-switch" type="checkbox"><div class="main">网站主体</div>
</body>

更多选择器的功能和分类请回看笔者这篇文章《可能是最全最易记的CSS选择器分类大法》。

切换按钮

打算设计一个美观的按钮,可是没有特别思路,就打开iPhone,把设置里的切换按钮用纯CSS实现一番。

尺寸和颜色都是与iPhone切换按钮一致。思路是使用<input>模拟按钮,声明appearance:none将其默认外观抹去,使用::before模拟背景区域,使用::after模拟点击区域,在触发:checked后添加一些小动画进行修饰,近乎完美地实现了iPhone切换按钮

切换按钮
<input class="ios-switch" type="checkbox">
.btn {border-radius: 31px;width: 102px;height: 62px;background-color: #e9e9eb;
}
.ios-switch {position: relative;appearance: none;cursor: pointer;transition: all 100ms;@extend .btn;&::before {position: absolute;content: "";transition: all 300ms cubic-bezier(.45, 1, .4, 1);@extend .btn;}&::after {position: absolute;left: 4px;top: 4px;border-radius: 27px;width: 54px;height: 54px;background-color: #fff;box-shadow: 1px 1px 5px rgba(#000, .3);content: "";transition: all 300ms cubic-bezier(.4, .4, .25, 1.35);}&:checked {background-color: #5eb662;&::before {transform: scale(0);}&::after {transform: translateX(40px);}}
}

请戳这里????查看在线演示与源码。(https://codepen.io/JowayYoung/pen/KKzgWaz)

暗黑模式

还记得4月4日那次全网开启悼念模式吗?笔者发表了一篇文章《一行代码全站进入悼念模式》,巧妙地使用filter这个强大的CSS属性。

html {filter:grayscale(1);
}

真的是一行代码,本次也不例外,一行代码全站进入暗黑模式

html {filter: invert(1) hue-rotate(180deg);
}

filter的兼容性不差,各位同学可放心使用,还有一些细节地方需注意,本文就不重复讲解了,详情可回看《一行代码全站进入悼念模式》。

filter是一个非常神奇的属性,能将Photoshop一些基础的滤镜效果应用到网站上。笔者平时非常喜欢使用filter,在笔者的CodePen上有许多纯CSS特效都使用了filter,细心的同学可能会发现笔者特别喜欢使用hue-rotate()这个函数结合CSS变量动态生成过渡颜色,详情请回看《妙用CSS变量,让你的CSS变得更心动》。

本次的暗黑模式使用到两个滤镜函数:invert()hue-rotate()

  • invert():反相,反向输出图像着色,值为0%则无变化,值为0~100%则是线性乘子效果,值为100%则完全反转

  • hue-rotate():色相旋转,减弱图像着色,处理非黑白的颜色,值为0deg则无变化,值为0~360deg则逐渐减弱,值超过360deg则相当绕N圈再计算剩余的值

invert()简单理解就是黑变白,白变黑,黑白颠倒hue-rotate()简单理解就是冲淡颜色。为了确保主题色调不会改变,将色相旋转声明为180deg比较合理。

依据上述分析的思路,当按钮处于选中状态时使用+/~连带后面的同胞元素也进入选中状态。若同胞元素无背景色需声明background-color:#fff,否则无法让滤镜效果起效,为了让这个同胞元素在使用滤镜效果时过渡得更自然,声明transition:all 300ms

.ios-switch {...&:checked {...& + .main {filter: invert(1) hue-rotate(180deg);}}
}
.main {background-color: #fff;transition: all 300ms;
}

在CodePen上为了更好地展示效果,就使用<iframe>引入我们最爱的搜狐门户,免费为其增加暗黑模式切换功能????。同时在排版上做了少量修改,请戳这里查看在线演示与源码。

暗黑模式

优化

细心的同学可能会发现,怎么图片都变成照B超的感觉了。

缺陷

按照设计原则来说,换肤只针对组件,像一些媒体类型的元素,例如背景、图片、视频等,都是不能直接处理的,需保持其原样。既然暗黑模式是使用了滤镜的反相和色相旋转实现,那么对这些媒体元素再次使用滤镜的反相和色相旋转就能复原了。使用过Photoshop滤镜的同学应该会更清楚。

img,
video {filter: invert(1) hue-rotate(180deg);
}

还有一个问题,背景怎样处理?众所周知,背景是使用background系列属性进行声明的,因此无法通过特定的选择器进行标注。但是,可换种思路处理,就是给有背景的元素加上一个特定类名,将其包含到上述规则里即可。

通过Chrome DevTools查看搜狐门户的网站源码,发现这些头像、缩略图和展示图都有一些特定类名,将其特定类名添加到规则里。

img,
video,
.logo,
.icon,
.jubao-con {filter: invert(1) hue-rotate(180deg);
}

在通用网站里,这个类名可自行定义,最可行的方法就是定义一个特定类名.exclude。不使用滤镜效果的元素统统加上.exclude

.exclude {filter: invert(1) hue-rotate(180deg);
}

改造

上述为了方便演示代码,在CodePen Demo里使用<iframe>引入我们最爱的搜狐门户。由于无法对<iframe>进行样式声明,所以转移到搜狐门户上,通过Chrome DevTools直接改造。

Chrome浏览器里按F12Cmd+Alt+I打开Chrome DevTools,分析网站的HTML结构。

<body><header class="sohu-head"></header><div class="sohu-ph" id="sohuTopc" style="display:none;"></div><div class="top-box"></div><div class="wrapper-box"></div>...
</body>

<body>里插入切换按钮

<body><input class="ios-switch" type="checkbox"><header class="sohu-head"></header><div class="sohu-ph" id="sohuTopc" style="display:none;"></div><div class="top-box"></div><div class="wrapper-box"></div>...
</body>

把以下SCSS代码转换成CSS代码插入到<head>新建的<style>里。推荐一个在线SASS转CSS的工具网站,复制以下代码到网站里直接转换,完成后再贴到<style>里。

值得注意,<input>后面的同胞元素是<header>和多个<div>,所以将+换成~响应多个同胞元素。

.btn {border-radius: 31px;width: 102px;height: 62px;background-color: #e9e9eb;
}
.ios-switch {position: relative;appearance: none;cursor: pointer;transition: all 100ms;@extend .btn;&::before {position: absolute;content: "";transition: all 300ms cubic-bezier(.45, 1, .4, 1);@extend .btn;}&::after {position: absolute;left: 4px;top: 4px;border-radius: 27px;width: 54px;height: 54px;background-color: #fff;box-shadow: 1px 1px 5px rgba(#000, .3);content: "";transition: all 300ms cubic-bezier(.4, .4, .25, 1.35);}&:checked {background-color: #5eb662;&::before {transform: scale(0);}&::after {transform: translateX(40px);}& ~ header,& ~ div {filter: invert(1) hue-rotate(180deg);img,video,.logo,.icon,.jubao-con {filter: invert(1) hue-rotate(180deg);}}}
}
.ios-switch ~ header,
.ios-switch ~ div {background-color: #fff;transition: all 300ms;
}

完成后发现切换按钮没有出现,可通过position:absolute将其绝对定位到想要显示的位置。

.ios-switch {position: absolute;right: 0;top: 0;z-index: 99999;outline: none;
}

或在<input>后的某个<div>里任意地方创建一个<label>,通过声明<input class="ios-switch" id="toggle" hidden><label for="toggle">互相绑定,将<input>的触发区域转移到<label>上。具体怎样实现,可参照笔者这个纯CSS标签导航栏实现。

若觉得讲解有点乱,可稍作整理,三步完成上述操作。

打开搜狐门户网站

F12Cmd+Alt+I打开Chrome DevTools

<head>里插入<style>

为了方便复制粘贴,笔者将上述分析得出的CSS代码进行压缩。

<style>.btn,.ios-switch::before,.ios-switch{border-radius:31px;width:102px;height:62px;background-color:#e9e9eb;}.ios-switch{position:relative;appearance:none;cursor:pointer;transition:all 100ms;}.ios-switch::before{position:absolute;content:"";transition:all 300ms cubic-bezier(0.45,1,0.4,1);}.ios-switch::after{position:absolute;left:4px;top:4px;border-radius:27px;width:54px;height:54px;background-color:#fff;box-shadow:1px 1px 5px rgba(0,0,0,0.3);content:"";transition:all 300ms cubic-bezier(0.4,0.4,0.25,1.35);}.ios-switch:checked{background-color:#5eb662;}.ios-switch:checked::before{transform:scale(0);}.ios-switch:checked::after{transform:translateX(40px);}.ios-switch:checked ~ header,.ios-switch:checked ~ div{filter:invert(1) hue-rotate(180deg);}.ios-switch:checked ~ header img,.ios-switch:checked ~ header video,.ios-switch:checked ~ header .logo,.ios-switch:checked ~ header .icon,.ios-switch:checked ~ header .jubao-con,.ios-switch:checked ~ div img,.ios-switch:checked ~ div video,.ios-switch:checked ~ div .logo,.ios-switch:checked ~ div .icon,.ios-switch:checked ~ div .jubao-con{filter:invert(1) hue-rotate(180deg);}.ios-switch ~ header,.ios-switch ~ div{background-color:#fff;transition:all 300ms;}.ios-switch{position:absolute;right:0;top:0;z-index:99999;outline:none;}</style>

<body>里插入<input>

<body><input class="ios-switch" type="checkbox"><header class="sohu-head"></header><div class="sohu-ph" id="sohuTopc" style="display:none;"></div><div class="top-box"></div><div class="wrapper-box"></div>...
</body>

就这样,一个纯CSS的实现方案就能让网站瞬间拥有暗黑模式切换功能,有没有又对CSS刮目相看了。

三步操作

总结

整个纯CSS实现方案围绕着:checked+/~filter三个点进行,缺一不可。看似简单,若不是常用CSS做特效也很难想象出区区三个点打辅助也能完成一个这么强大的功能。

<body><input class="ios-switch" type="checkbox"><div class="main">网站主体</div>
</body>
.ios-switch {...&:checked {...& + .main {filter: invert(1) hue-rotate(180deg);img,video,.exclude {filter: invert(1) hue-rotate(180deg);}}}
}
.main {background-color: #fff;transition: all 300ms;
}

相比于CSS+JS实现方案而言,无需维护一整套暗黑模式样式代码,无需操作DOM,没有了往常复杂的操作。除非要做一整套高度定制的暗黑模式才需一个CSS+JS实现方案,否则用该方案即可。

本方案具有以下特点。

  • 纯CSS实现,简单高效,逼格更高

  • 几乎没有维护成本,快速迭代

  • 充分利用滤镜效果,兼容性好

试试无妨,完成了觉得效果不错就赶紧找你老板加薪去吧????!

本期赠书

《Web前端性能优化》陈铎鑫 著

本书以Web性能优化为重点,深入浅出地介绍了性能优化所涉及到的方方面面知识,详细解答了为何要做性能优化,性能优化又需要从何处着手,性能优化的过程又需要考虑到哪些问题?需要做怎样的权衡?

活动参与方式:留言点赞数前三名的同学各获赠书一本

获奖公布时间及位置:11月19日头条推送文末

特别提醒:兑奖截止至11月26日,请参与读者及时兑奖

加入搜狐技术作者天团

千元稿费等你来!

???? 戳这里!

也许你还想看

(▼点击文章标题或封面查看)

【文末有惊喜!】带你深入理解不一样的 Flutter

2020-10-29

2020年你必须知道的webpack打包优化方法

2020-04-02

20个你不得不知道的数组reduce高级用法

2020-02-13

深入理解http2.0协议,看这篇就够了!

2019-10-31

彻底搞懂移动Web开发中的viewport与跨屏适配

2019-11-07

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_792206.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

30个让人兴奋的视差滚动(Parallax Scrolling)效果网站--转

视差滚动&#xff08;Parallax Scrolling&#xff09;是指让多层背景以不同的速度移动&#xff0c;形成立体的运动效果&#xff0c;带来非常出色的视觉体验。作为今年网页设计的热点趋势&#xff0c;越来越多的网站应用了这项技术。今天这篇文章就与大家分享30个视差滚动效果的…

前端通用SEO技术优化指南

本文字数&#xff1a;2585字预计阅读时间&#xff1a;8分钟背景近期团队开发的新产品的官网上线了&#xff0c;随之而来的问题就是如何让网站更快更好的传播出去。当然SEO就是最常见的手段之一&#xff0c;对官网的SEO工作有利于产品的网络传播和分享。有的团队会有专人负责SEO…

Windows Server 2008 R2服务器在IIS上添加网站

1、安装网站之前&#xff0c;我们先需要确定aspx模块是否安装成功&#xff0c;在管理工具下找到IIS管理器&#xff0c;在IIS管理器下找到应用程序池&#xff0c;单击右键选择添加应用程序池&#xff0c;即可弹出相关的弹出框。 我们看到.NET Framework版本中看到有2.0和4.0版本…

bugku-网站被黑(这个题没技术含量但是实战中经常遇到)

题目地址&#xff1a;http://123.206.87.240:8002/webshell/ 进去之后没什么特别的提示 但题目说了 实战 经常遇到 所以 直接 御剑 跑一下 http://123.206.87.240:8002/webshell/shell.php 进入到一个 后台登陆页面 打开burp 使用burp中的 Intruder模块 爆破 用bur…

访问服务器网站出现 HTTP ERROR 500 该网页无法正常运作

项目在本地写好后上传到服务器访问出现如下图所示&#xff1a; 经过查看php日志文件发现问题在于数据库连接错误&#xff0c;如下图&#xff1a; 将项目中数据库配置部分修改成服务器中数据库的用户名和密码&#xff0c;重启服务器即可正常访问。

网站设计中常用的一些jq效果

只做会做网站设计不会前端是不行的&#xff0c;现在很多网站设计师都会精通前端CSSjquery&#xff0c;但是今天要说的是是我个人在一家厦门网站设计公司中经验笔记&#xff0c;都是很实用的&#xff0c;希望能帮助网站设计者们&#xff0c;现在越来越多的网站运用上了Jquery技术…

如何利用Python监控你女/男朋友每天都在浏览什么网站?

需求&#xff1a; (1) 获取你对象chrome前一天的浏览记录中的所有网址(url)和访问时间&#xff0c;并存在一个txt文件中 (2)将这个txt文件发送给指定的邮箱地址(你的邮箱) (3)建立例行任务&#xff0c;每天定时自动完成这些操作&#xff0c;你就可以通过邮件查看你对象每天看…

给你8个接私活的网站,保证你月薪轻松上W

今天给大家推荐几个江湖卖艺赚钱养家的好渠道&#xff08;程序员&#xff1a;8个接私活的网站&#xff0c;只要你有码&#xff0c;那“我”就有钱&#xff01;&#xff09;一起来看看吧&#xff01; 1、程序员客栈 https://www.proginn.com/ 2、快码众包 https://www.kuai.m…

不会吧,学过爬虫连这个网站都爬不了?那Python岂不是白学了

本文内容 系统分析目标网页html标签数据解析方法海量图片数据一键保存 环境介绍 python 3.8pycharm 模块使用 requests >>> pip install requestsparsel >>> pip install parseltime 时间模块 记录运行时间 通用爬虫 导入模块 import requests # 数…

工程师英语和计算机证书查询,点击进入国家硬件维修工程师证书查询网站

工程师证书查询网站人力资源社会保障部指定查询国家职业资格证书的唯一官方网站。涵盖全国各省市、各行业、各央企颁发的证书。电脑硬件维修工程师网上能查看国家工信部硬件维修工程师证书查询网址&#xff1a;http://www.ceiaec.org/index.htm工程师证书编号在网上怎么查询如果…

根目录_怎样找到网站根目录?

什么是根目录&#xff1f;什么是根目录&#xff1f;根目录&#xff0c;或根文件夹&#xff0c;是顶层目录一个的文件系统。目录结构可以直观地表示为上下颠倒的“树”&#xff0c;因此术语“ root ”代表顶层。所有其它目录、子目录、目录的“分支”等都储存在根目录中。尽管所…

网站服务器怎么理解,http请求的原理怎么理解

(1)是请求方法&#xff0c;GET和POST是HTTP中最常用的方法&#xff0c;除了DELETE、HEe、OPT、NS、PUT和Sea之外。但目前大多数浏览器仅支持GET和POST。它提供了一个HiddenHtyMethodFilter&#xff0c;可以让你通过“_method”的表单参数来指定这些特殊的HTTP方法(实际上&#…

Tornado 网站demo 二

连接数据库 methods 中建立一个文件 db.py 分别建立起连接对象和游标对象 #!/usr/bin/env Python # codingutf-8import pymysql conn pymysql.connect(host"localhost", user"root", passwd"123456", db"testdb", port3306, charset&…

【redux】详解react/redux的服务端渲染:页面性能与SEO

亟待解决的疑问 为什么服务端渲染首屏渲染快&#xff1f;&#xff08;对比客户端首屏渲染&#xff09; react客户端渲染的一大痛点就是首屏渲染速度慢问题&#xff0c;因为react是一个单页面应用&#xff0c;大多数的资源需要在首次渲染前就加载好&#xff0c;这较大程度地拖慢…

顶级白嫖!!!八个python免费自学网站一周搞定python(抓紧收藏)。。

导读 人工智能必将到来&#xff0c;在那个时代&#xff0c;我们的工作方式会发生很大的改变&#xff0c;尤其是Python都已经进入了中小学教育的大纲&#xff0c;在智能为主的时代&#xff0c;Python就像现在的电脑一样&#xff0c;每个人工作中必备的工作技能&#xff0c;学会…

新手学电脑入门教程_适合新手程序员学习编程的10个常用网站,超实用

我们很多程序员刚学习时都到处找资源&#xff0c;今天小编我把最常用的10个编程网站分享给大家&#xff0c;大家只要经常浏览这10个网站&#xff0c;学好编程足够了。1、 Googlehttps://www.google.com/2、Stackoverflowhttp://stackoverflow.com/3、githubhttps://github.com/…

页面布局让footer居页面底部_谷歌SEO的网站页面内链布局3大方法!

在谷歌SEO里&#xff0c;网站中内链的重要性不言而喻。对于用户来说&#xff0c;合理的网站内链可以方便用户读取有用的信息&#xff0c;提升用户粘性&#xff0c;降低跳出率。从谷歌搜索引擎来说&#xff0c;合理的网站内链&#xff0c;不仅能够吸引谷歌搜索引擎蜘蛛的抓取&am…

阿里云云主机搭建网站攻略 - 云翼计划

阿里云服务器&#xff08;云主机&#xff09;搭建网站攻略 - 云翼计划 提示&#xff1a;此搭建攻略为2017版本&#xff0c;阿里云未跟新前。 最新搭建攻略请前往 Amaya丶夜雨博客 / 最新个人博客 https://www.amayaliu.cn 支持一下哦&#xff0c;谢谢。&#xff08;9.5一…

在网站中添加 https 百度分享

博客地址&#xff1a;http://www.moonxy.com 一、前言 百度分享是一个提供网页地址收藏、分享及发送的 WEB2.0 按钮工具&#xff0c;借助百度分享按钮&#xff0c;网站的浏览者可以方便的分享内容到人人网、开心网、QQ空间、新浪微博等一系列 SNS 站点。 网站主可以在百度分享网…

python3.6使用django-oscar搭建商店网站_使用Django搭建网站实现商品分页功能

装好Django&#xff0c;写好index.html后&#xff0c;可以展示网页了。但是这只是静态页面&#xff0c;没有关联数据库&#xff0c;也不能分页展示商品信息。本节连接mongodb数据库(事先已准备好数据)&#xff0c;从中取出几十条商品信息&#xff0c;每页展示4个商品信息&#…