不建议跳跃阅读!
这篇文章将从头开始介绍如何实现一个特效
中间偶尔会穿插一些css3或平时接触不多的css属性
首先看一看这一期的特效:
HTML部分
<div class="loader"></div>
CSS 部分
既然是一个加载特效,那么我们可以将loader
垂直居中的放在页面上,这里采用的是grid布局的方法:
body {
height:100vh;
display:grid;
place-content:center;
}
也许你曾经没有接触过grid布局
,所以这里介绍一些常见的grid用法
grid布局
它可以将容器划分为行和列,产生单元格,然后操作项目所在的单元格,可以将grid布局看作是二维布局(平时使用的可能更为广泛的flex布局
则是针对items的轴线来判定,可以看作是一维布局)
grid-template-*
既然是二维布局,那么肯定也存在行列的设置:
- grid-template-columns:表示列
- grid-template-rows:表示行
以上面的图片为例,我们需要一个三行四列的布局,因此可以这样做:
grid-template-columns:100px 100px 100px;
grid-template-rows:100px 100px 100px 100px;
grid-template-columns:repeat(3,100px);
grid-template-rows:repeat(4,100px);
grid-template-columns:repeat(3,1fr);
grid-gap
除了可以设置行列的条数,还可以设置每个item之间的距离gap
看到这里你可能会想:“那就通过`grid-column-gap和grid-row-gap设置间隔大小就可以了”
这在以前是正确的,可是注意:根据最新标准,gap相关的grid-前缀已经删除, grid-column-gap和grid-row-gap写成column-gap
和row-gap
,他俩的简写grid-gap写成gap
,比如:
row-gap:20px;
column-gap:20px;
gap:20px 20px;
垂直和水平布局方式
grid中控制垂直和水平布局方式的属性名称和flex布局类似:
- 通过
justify-items
控制水平方向上,二维数组的每一个item中元素的对齐格式 - 通过
align-items
控制垂直方向上,二维数组的每一个item中元素的对齐格式 - 简写:
place-items:xx, xx
比如:
justify-items: start;
justify-content: space-around;
好了,现在了解这些就可以了,现在再来看看之前的代码:
body {
height:100vh;
display:grid;
place-content:center;
}
这段css的意思是设置body采用grid布局,并且让body中的元素在水平和垂直方向上都处于center的位置上
现在我们让loader垂直居中了,为他加一些样式:
.loader {
width: 200px;
aspect-ratio: 1;
display: grid;
background: linear-gradient(135deg,#00A8C6,#8FBE00);
clip-path: inset(10%);
}
aspect-ratio
在响应式网页设计中,保持一致的宽高比,即所谓的长宽比,对于防止布局累积偏移至关重要。在 Chromium 88、Firefox 87 和 Safari Technology Preview 版本中推出了 aspect-ratio 属性,我们有了更直接的方法来实现这一目标。
长宽比最常见的表示形式为:宽:高
,摄影最常见的长宽比是 4:3 和 3:2 ,而视频和最近的消费类相机则倾向于16:9的长宽比。
随着响应式设计的出现,保持长宽比对于我们来说越来越重要。比如当我们改变显示区域大小时,div元素
的长宽比也会保持不变,改变的只是长宽的数值。在一些场景下,维持长宽比显得非常的有用,比如:
.container {
width: 100%;
aspect-ratio: 16 / 9;
}
我们都知道在前端开发中经常遇到需要保持一个元素的长宽比的问题,最常见的就是我们的Img元素
、video元素
这种本身就具有长宽比的元素。
使用auto属性,可替换元素(img、video这种本身就具有长宽比的元素)将继续保持它原本的长宽比,不会受css属性的影响。
如果希望在改变可视区域元素的长宽比时,让img
元素维持原来的长宽比,可以这样做:
.container {
width: 300px;
aspect-ratio: auto 2 / 1;
}
好了,知道这些就够用了。这篇文章的介绍挺详细的,想要了解更多的话可以点进去看看。
我们为.loader
标签设置aspect-ratio:1
时可以有效地保证加载特效的1: 1展示。
回想之前的特效,正中心的.loader
元素分开形成了四个小的圆圈,这些圆圈当然可以说是新增四个小的div来实现,但是这样就慢了。我们可以通过伪元素:before
设置。
不过,按照以前的角度来想:“:before
好像只能设置一个元素吧?“
这就错了,在css3中background
属性可以设置多张背景!
css3 background特殊用法
MDN文档中的解释如下:
background
属性被指定多个背景层时,使用逗号分隔每个背景层。
每一层的语法如下:
- 在每一层中,下列的值可以出现 0 次或 1 次:
<attachment>
<bg-image>
<position>
<bg-size>
<repeat-style>
<bg-size>
只能紧接着 <position>
出现,以"/"分割,如: “center/80%
”.<box>
可能出现 0 次、1 次或 2 次。如果出现 1 次,它同时设定 background-origin
和 background-clip
。如果出现 2 次,第一次的出现设置 background-origin
,第二次的出现设置 background-clip
。<background-color>
只能被包含在最后一层。
因此,我们可以写出以下代码:
.loader:before {
content: "";
padding: 10%;
--_g: no-repeat content-box radial-gradient(50% 50%,#000 95%,#0000);
background: var(--_g),var(--_g),var(--_g),var(--_g),#fff;
background-size: 20% 20%;
filter: blur(5px) contrast(20);
mix-blend-mode: lighten;
}
好了,现在我们已经实现了最关键的一步:成功的创建了四个小圆,由于我们没有对它们进行定位,所以现在四个小圆的圆心重叠的位于左上角,由于采用的是padding: 10%;
,可以让圆圈向下向右移动一些。
现在来实现动画效果:
@keyframes l {
0%,
100%{background-position:top,right,bottom,left}
20% {background-position:center,right ,bottom,left}
40% {background-position:center,center,bottom,left}
60% {background-position:center,center,center,left}
80% {background-position:center,center,center,center}
}
光是小球的移动可能会有些单调,所以我们再加一些放大效果,看起来更炫酷:
@keyframes s{
0%,
25%,
90% {background-size:20% 20%}
40%,
45%{background-size:30% 30%,20% 20%,20% 20%,20% 20%}
60%,
65%{background-size:40% 40%,20% 20%,20% 20%,20% 20%}
80%{background-size:50% 50%,20% 20%,20% 20%,20% 20%}
}
最后在.loader:before
中添加上动画效果:
.loader:before {
content: "";
padding: 10%;
--_g: no-repeat content-box radial-gradient(50% 50%,#000 95%,#0000);
background: var(--_g),var(--_g),var(--_g),var(--_g),#fff;
background-size: 20% 20%;
filter: blur(5px) contrast(20);
mix-blend-mode: lighten;
animation: l 3s infinite,s 3s infinite;
}
搞定,看看最终的效果吧:
完整代码
代码参考自codepen
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>黑猫几绛 |</title>
</head>
<style>
body {
height:100vh;
display:grid;
place-content:center;
}
.loader {
width: 200px;
aspect-ratio: 1;
display: grid;
background: linear-gradient(135deg,#00A8C6,#8FBE00);
clip-path: inset(10%);
}
.loader:before {
content: "";
padding: 10%;
--_g: no-repeat content-box radial-gradient(50% 50%,#000 95%,#0000);
background: var(--_g),var(--_g),var(--_g),var(--_g),#fff;
background-size: 20% 20%;
filter: blur(5px) contrast(20);
mix-blend-mode: lighten;
animation: l 3s infinite,s 3s infinite;
}
@keyframes l {
0%,
100%{background-position:top,right,bottom,left}
20% {background-position:center,right ,bottom,left}
40% {background-position:center,center,bottom,left}
60% {background-position:center,center,center,left}
80% {background-position:center,center,center,center}
}
@keyframes s{
0%,
25%,
90% {background-size:20% 20%}
40%,
45%{background-size:30% 30%,20% 20%,20% 20%,20% 20%}
60%,
65%{background-size:40% 40%,20% 20%,20% 20%,20% 20%}
80%{background-size:50% 50%,20% 20%,20% 20%,20% 20%}
}
</style>
<body>
<div class="loader"></div>
</body>
</html>
思考:现在假设有一个需求,需要实现八个小球在水平垂直的位置不停旋转,你会怎么做?
提示:用这篇文章介绍过的方法可以实现。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)