纯CSS免费让⽹站拥有暗⿊模式切换功能的实现代码
前⾔
暗⿊模式这个概念最早起源于MacOS系统的Mojave,提供浅⾊主题和深⾊主题两种⽪肤供⽤户选择,深⾊主题就是我们常说的暗⿊模式。为了眼睛健康,笔者在⼿机、平板和电脑上都选择了暗⿊模式。
随着苹果官⽅逐渐要求各⼤系统平台都得适配暗⿊模式,所以笔者也探索出⼀种应该是市⾯上最低成本的⽹站暗⿊模式适配⽅案。
认识笔者的朋友应该都知道笔者是⼀位重度CSS发烧友,当然这次也是使⽤纯CSS实现这个⽅案。是的,不加任何⼀段JS,侧⾯再次证明CSS的强⼤。
思路
思路很简单,使⽤⼀个按钮来回切换主题样式。按钮未选中则切换到浅⾊主题,按钮选中则切换到深⾊主题。可⽤:checked和+打辅助完成这个任务。
:checked :选项选中的表单元素
+ :元素相邻的同胞元素
使⽤<input>模拟按钮,当按钮处于选中状态时触发:checked,通过+带动后⾯相邻的⽹站主体<div>进⼊暗⿊模式,选中状态取消时则退出暗⿊模式。
<body>
<input class="ios-switch" type="checkbox">
<div class="main">⽹站主体</div>
</body>
更多选择器的功能和分类请回看笔者这篇⽂章《可》。
切换按钮
打算设计⼀个美观的按钮,可是没有特别思路,就打开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);
}
}
请戳查看在线演⽰与源码。
暗⿊模式
还记得4⽉4⽇那次全⽹开启悼念模式吗?笔者发表了⼀篇⽂章《》,巧妙地使⽤filter这个强⼤的CSS属性。
html {
filter:grayscale(1);
}
真的是⼀⾏代码,本次也不例外,⼀⾏代码全站进⼊暗⿊模式。
html {
filter: invert(1) hue-rotate(180deg);
}
filter的兼容性不差,各位同学可放⼼使⽤,还有⼀些细节地⽅需注意,本⽂就不重复讲解了,详情可回看《》。
filter是⼀个⾮常神奇的属性,能将Photoshop⼀些基础的滤镜效果应⽤到⽹站上。笔者平时⾮常喜欢使⽤filter,在笔者的上有许多纯CSS特效都使⽤了filter,细⼼的同学可能会发现笔者特别喜欢使⽤hue-rotate()这个函数结合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;
}
在上为了更好地展⽰效果,就使⽤<iframe>引⼊我们最爱的掘⾦社区,免费为其增加暗⿊模式切换功能:wink:。同时在排版上做了少量修改,请戳查看在线演⽰与源码。
优化
细⼼的同学可能会发现,怎么图⽚都变成照B超的感觉了。
按照设计原则来说,换肤只针对组件,像⼀些媒体类型的元素,例如背景、图⽚、视频等,都是不能直接处理的,需保持其原样。既然暗⿊模式是使⽤了滤镜的反相和⾊相旋转实现,那么对这些媒体元素再次使⽤滤镜的反相和⾊相旋转就能复原了。使⽤过Photoshop滤镜的同学应该会更清楚。
img,
video {
filter: invert(1) hue-rotate(180deg);
}
还有⼀个问题,背景怎样处理?众所周知,背景是使⽤background系列属性进⾏声明的,因此⽆法通过特定的选择器进⾏标注。但是,可换种思路处理,就是给有背景的元素加上⼀个特定类名,将其包含到上述规则⾥即可。
通过Chrome DevTools查看掘⾦社区的⽹站源码,发现这些头像、缩略图和展⽰图都有⼀些特定类名,将其特定类名添加到规则⾥。
img,
video,
.avatar,
.image,
.thumb {
filter: invert(1) hue-rotate(180deg);
}
在通⽤⽹站⾥,这个类名可⾃⾏定义,最可⾏的⽅法就是定义⼀个特定类名.exclude。不使⽤滤镜效果的元素统统加上.exclude。
.exclude {
filter: invert(1) hue-rotate(180deg);
改造
上述为了⽅便演⽰代码,在⾥使⽤<iframe>引⼊我们最爱的掘⾦社区。由于⽆法对<iframe>进⾏样式声明,所以转移到掘⾦社区上,通过Chrome DevTools直接改造。
在Chrome浏览器⾥按F12或Cmd+Alt+I打开Chrome DevTools,分析⽹站的HTML结构。
<body>
<div id="__nuxt">...</div>
</body>
往<body>⾥插⼊切换按钮。
<body>
<input class="ios-switch" type="checkbox">
<div id="__nuxt">...</div>
</body>
把以下SCSS代码转换成CSS代码插⼊到<head>新建的<style>⾥。推荐⼀个在线SASS转CSS的,复制以下代码到⽹站⾥直接转换,完成后再贴到<style>⾥。
.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);
}
& + #__nuxt {
filter: invert(1) hue-rotate(180deg);
img,
video,
.avatar,
.
image,
.thumb {
filter: invert(1) hue-rotate(180deg);
}
}
}
}
#__nuxt {
background-color: #fff;
transition: all 300ms;
}
好看的css代码完成后发现切换按钮没有出现,可通过position:absolute将其绝对定位到想要显⽰的位置。
.ios-switch {
position: absolute;
right: 0;
top: 0;
z-index: 99999;
outline: none;
}
或在<div id="__nuxt">⾥任意地⽅创建⼀个<label>,通过声明<input class="ios-switch" id="toggle" hidden>和<label for="toggle">互相绑定,将<input>的触发区域转移到<label>上。具体怎样实现,可参照笔者这个
实现。
若觉得讲解有点乱,可稍作整理,三步完成上述操作。
打开掘⾦社区⽹站
按F12或Cmd+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 300m 往<body>⾥插⼊<input>
<body>
<input class="ios-switch" type="checkbox">
<div id="__nuxt">...</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实现,简单⾼效,逼格更⾼
⼏乎没有维护成本,快速迭代
充分利⽤滤镜效果,兼容性好
试试⽆妨,完成了觉得效果不错就赶紧你⽼板加薪去:stuck_out_tongue_winking_eye:,哈哈!
到此这篇关于纯CSS免费让⽹站拥有暗⿊模式切换功能的实现代码的⽂章就介绍到这了,更多相关CSS暗⿊模式切换内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章,希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论