最近微信也逃脱不了黑暗时代的到来,网页也很多都做了黑暗模式的兼容和主题。如果我们在做的一个网站想瞬间实现黑暗模式可以怎么实现呢?
其实有一个很快的方式,我们可以使用invert和hue-rotate两个CSS3过滤器来实现。
filter: invert() — 是从0到1的刻度,1是从白变黑。 filter: hue-rotate() — 用于改变你元素的颜色,同时或多或少保持原本相同的色系。这个属性的值可以从0deg到360deg。
在我们页面的body标签上添加这两个属性,我们就可以快速尝试把我们的网站变成"黑暗模式"。这里需要注意的是,如果body和html上没有设置background背景颜色,这个过滤就会不起效了哦。
CSS的代码如下:
html {
background: #fff;
}
body {
background: #fff;
filter: invert(1) hue-rotate(270deg);
}
实现效果
这里我们会发现图片的颜色会受影响,并不是很美观,使用css过滤器是无法完美切换黑暗模式的。不过使用JavaScript辅助就可以完美的切换黑暗模式。
最近出了一个JavaScript辅助插件叫Darkmode.js。
Darkmode.js
其实Darkmode.js运用的也是css里面的一个特性叫mix-blend-mode — “CSS 属性描述了元素的内容应该与元素的直系父元素的内容和元素的背景如何混合“。加上Javascript的辅助判断哪些页面上的元素需要黑化的,哪些是不需要黑化的。就会想我们之前那种做法,导致其他不需要黑化的元素,比如图片,受到影响导致颜色出现问题。
使用Darkmode.js非常简单,只要在脚本里面添加以下代码就可以马上加入一个插件,
<script src="https://cdn.jsdelivr.net/npm/darkmode-js@1.5.5/lib/darkmode-js.min.js"></script>
<script>
// 这些是这个插件的可配置项:
var options = {
bottom: "32px", // 定位底部距离 - 默认: '32px'
right: "32px", // 定位右边距离 - 默认: '32px'
left: "unset", // 定位左边距离 - 默认: 'unset'
time: "0.5s", // 默认动画时间: '0.3s'
mixColor: "#fff", // 需要改变的颜色 - 默认: '#fff'
backgroundColor: "#fff", // 背景颜色 - 默认: '#fff'
buttonColorDark: "#262728", // 黑暗模式下按钮颜色 - 默认: '#100f2c'
buttonColorLight: "#fff", // 日间模式下按钮颜色 - 默认: '#fff'
saveInCookies: true, // 是否在cookie保存当前模式 - 默认: true,
label: "", // 切换模式按钮图标 - 默认: ''
autoMatchOsTheme: true // 是否自动根据系统适应模式 - 默认: true
};
let darkmode = new Darkmode(options);
darkmode.showWidget();
</script>
如果你不希望用这个插件的默认按钮,你可以在你的JavaScript代码中自主控制。我们可以通过.toggle()方法来切换模式,同时可以使用.isActivated()来检测是否已经进入黑暗模式。
const darkmode = new Darkmode();
darkmode.toggle();
console.log(darkmode.isActivated()) // 如果已经进入黑暗模式会返回 true
4. 自定义列表符号知识总结
filter: invert() — 可以把页面从白变黑,也可以从黑变白。 filter: hue-rotate() — 用于改变你元素的颜色,同时或多或少保持原本相同的色系。 Darkmode.js — 瞬间实现黑暗模式。
ul,li的无序列表有默认的符号·,但是在很多情况下我们希望可以给这个符号加入自己的样式和颜色,甚至是换成自定义的符号。默认的符号我们是无法做任何的样式处理,而且默认的符号在CSS属性里面只有几个选择可以使用,很多情况下都是无法满足我们的设计。
其实自定义无序列表符号不难,我们只需要使用伪类::before加content属性就可以实现。
在我这个例子里面我做了两个任务列表,一个是待处理任务,一个是已完成任务,各自给了不一样的列表符号和颜色。
实现原理
一、首先我们禁用了ul的默认符号样式list-style: none
二、在li的:before伪类上给予content内容值,待处理任务使用,已完成任务li.completed:before使用✔
三、为了展示效果更加好看我分别给了li和li .completed两个不同的颜色
上代码看看是怎么实现的吧:
HTML
<div>
<h2>待处理</h2>
<ul>
<li>待办任务1</li>
<li>待办任务2</li>
<li>待办任务3</li>
<li>待办任务4</li>
<li>待办任务5</li>
</ul>
</div>
<div>
<h2>已完成</h2>
<ul>
<li class="completed">完成任务1</li>
<li class="completed">完成任务2</li>
<li class="completed">完成任务3</li>
</ul>
</div>
CSS
ul {
list-style: none;
color: #fff;
font-size: 20px;
border: 3px solid #000;
padding: 1rem 2rem;
min-height: 200px;
margin: 15px 2rem 0 0;
background: #323232;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
border-radius: 8px;
}
li {
padding: 0.3rem 0;
}
li::before {
content: " ";
color: aqua;
}
li.completed::before {
content: "✔ ";
text-decoration: none;
color: greenyellow;
}
li.completed {
text-decoration: line-through;
color: #bdbdbd;
}
::before和::after伪类加content属性可以用来做很多特殊的效果,也是当代前端排版比较常用的“魔法”。说到伪类的使用,我再给大家说一个比较常用的使用场景。
在管理后台或者是文章展示中,我们经常可以见到的“面包屑导航”也是用伪类来插入每个目录中间的符号的。
实现逻辑
一、这个导航含有3个a标签,首先给每个a标签加入一个伪类::after,然后在content属性插入/符号。
二、然后使用a:first-child,这个伪类会选择到第一个a标签,然后使用content属性加入»符号。
三、因为我们第一步在每个a标签的后面插入了/符号, 所以我们需要在最后一个a标签清除掉。这里我们使用:last-child选择到最后一个a标签,然后用content: " "属性把伪类的内容清楚掉。
HTML
<div class="breadcrumb">
<a>三钻</a>
<a>前端</a>
<a>教程</a>
</div>
CSS
.breadcrumb {
font-size: 1.6rem;
color: #fff;
}
.breadcrumb a:first-child {
color: #82fcfd;
}
.breadcrumb a:first-child::before {
content: " » ";
}
.breadcrumb a::after {
content: " /";
color: #ef6eae;
}
.breadcrumb a:last-child::after {
content: "";
}
5. 图片视差效果知识总结
::before | ::after — 伪类用于向某些选择器添加特殊的效果。 content — CSS 属性用于在元素的 ::before 和 ::after 伪元素中插入内容。使用content 属性插入的内容都是匿名的可替换元素。 :first-child — CSS伪类表示在一组兄弟元素中的第一个元素。 :last-child — CSS伪类代表父元素的最后一个子元素。