前言
之前学css的时候,发现了两个css相关的东西sass
,less
,这俩玩意用起来是很方便的,毕竟里面可以自定义变量、方法之类的,可以让很多重复的东西封装起来共用一套代码。
但是我发现一个问题,就是现在的vue项目(我遇到的项目)中,很少有人去用sass
或者less
,或者是用了,但是写法还是css的写法,并没有突出这两者的一些特性和区别。
接下来,为了让大家更好的理解和使用sass
,我会用一个星空背景的效果来实战一下,在sass
中要怎么去做一些封装的方法和变量。
先看效果
- 看过效果之后,你会发现这个效果其实并不难,而且也有很多的写法
- 比如
js+dom
或者js+canvas
,亦或者你直接用最简单的css
也是可以的
当然,如果你使用纯粹的css
去实现这个效果呢,你会发现这种方案简直太扎心了,写起来太麻烦了。
所以今天给大家用sass
的写法来实现,其实写这个效果并不是很重要,重要的是通过这个效果来把sass
里面的一些内容给讲解出来,并且让大家体验到sass
的写法能给我们的开发带来多大的便利。
页面
页面上的dom元素其实很简单,就是多个div
<div class="star1"></div>
<div class="star2"></div>
<div class="star3"></div>
<div class="title">蜡笔小心_</div>
背景样式和title的样式可以直接去到文章最后看码上掘金
的效果。
画星星
普通css画圆
- 画星星之前,我们得先了解星星的构造
- 在上面的效果图中,我们会发现,星星其实就是一个又一个小圆圈
- 那么我们就可以先从画圆开始
.star1{
position: fixed;
width: 100px;
height: 100px;
border-radius: 50%;
top: 0;
left: 0;
box-shadow: 10vw 10vh #fff;
}
- 我们利用
box-shadow
属性来画一个圆
大家可以思考一下
box-shadow
属性的用法,怎么用它来画更多的圆?
box-shadow: 10vw 10vh #fff, 20vw 20vh #fff, 30vw 30vh #fff;
- 其实在
box-shadow
属性中,可以通过逗号进行分割来表现出多种不同位置的元素
当我们知道,可以通过
box-shadow
属性中多条数据来画圆,那么是不是可以用一个for
循环来动态传递这个数据给css中的box-shadow
属性。
sass画圆
在使用sass画圆之前,我们需要了解一个知识点random
随机数
在上面的样式中,有宽高的样式,因为是圆,所以他们的宽高是一致的,那么我们是不是也可以提炼出来,当做一个共用的属性。
.star1{
$size: 50px;
position: fixed;
width: $size;
height: $size;
border-radius: 50%;
top: 0;
left: 0;
box-shadow: 10vw 10vh #fff, 20vw 20vh #fff, 30vw 30vh #fff;
}
- 在这个样式的最前面,我们定义了一个sass写法的通用样式
$size
- 并且我们在宽高属性中使用了它
和之前的圆相比,这个已经变小了,说明这个参数已经被动态设置进去了。
下面我们就可以用random
随机数的写法来动态实现不一样的宽高
$size: random(100);
- 当我们直接这样修改会是什么效果呢?
- 随机数已经放到宽高属性上了,但是没有起作用,因为没有带单位。
在sass中也有一种类似于es6中模板字符串的写法
#{}
$size: #{random(100)}px;
大家可以自己刷新页面之后看看是不是已经随机了?
知道随机数之后,我们就可以了解另外一个知识点function
,定义方法
@function shadowFun($n){
$shadows: '#{random(100)}vw #{random(100)}vh #fff';
@return unquote($shadows)
}
在样式中使用@function
可以和js中一样定义一个方法,这个方法里面接收一个参数(后面会讲到)
- 在方法里面,定义了一个
$shadows
变量,通过它来表示样式中的box-shadow
属性值 - 定义好变量之后,需要通过
@return
返回出去
由于
$shadows
是一个字符串,在return
的时候,我们需要将外层包裹的""
给去掉,所以使用了一个unquote
方法
在样式中的box-shadow
属性上直接调用这个方法即可。
box-shadow: shadowFun(1000);
- 由于只写了一个
$shadows
的值,所以页面上只有一个圆
接下来就开始使用 for
循环来画更多的圆
@function shadowFun($n){
$shadows: '#{random(100)}vw #{random(100)}vh #fff';
@for $i from 2 through $n {
$shadows: '#{$shadows}, #{random(100)}vw #{random(100)}vh #fff';
}
@return unquote($shadows)
}
- 在方法中通过
@for
的写法来表示循环体 - 由于上面已经定义了一个
$shadows
,所以循环体中是从 下标2
开始循环,一直循环到方法传递的参数结束。 - 在循环体中,我们将上面定义的
$shadows
重复写一遍即可。
.star1{
$size: #{random(1)}px;
position: fixed;
width: $size;
height: $size;
border-radius: 50%;
top: 0;
left: 0;
box-shadow: shadowFun(1000);
}
- 将
$size
的随机数变小一点,这样看起来就像星星了
- 由图可见,已经有了漫天的星星了。
有个问题,现在的星星已经出来,但是没有动画效果。
动起来
.star1{
$size: #{random(1)}px;
position: fixed;
width: $size;
height: $size;
border-radius: 50%;
top: 0;
left: 0;
box-shadow: shadowFun(1000);
animation: moveUp 10s linear infinite;
}
@keyframes moveUp{
100% {
transform: translateY(-100vh);
}
}
- 动画效果其实好像没什么好说的,大家肯定会觉得这个很简单
- 毕竟只是在样式里面添加了一个
animation
属性而已
但是当我们看到效果之后,我们会发现一个大问题,就是星星往上滚动一屏之后,就会消失了,然后抖动一下之后重新执行。
我们可以通过伪元素
after
来重新添加一屏,当然两屏的数据得是一样的才行,不然也会出现抖动的情况
.star1{
$size: #{random(1)}px;
position: fixed;
width: $size;
height: $size;
border-radius: 50%;
top: 0;
left: 0;
box-shadow: shadowFun(1000);
animation: moveUp 10s linear infinite;
&::after{
content: '';
position: fixed;
left: 0;
top: 100vh;
width: $size;
height: $size;
border-radius: inherit;
box-shadow: inherit;
}
}
border-radius
和box-shadow
两个属性值全部集成父级样式,就可以变成一样的了。
循环星空
一层星空太单调了,我们可以继续扩展for
循环的用法,来多做几层星空
此处大家可以继续思考一下,该怎么写这样一个循环体?(下面这段码上掘金代码中可以尝试一下哦!)
- 以下是
for
循环源码展示
$time: 100s;
$count: 800;
@for $i from 1 through 3{
$time: floor($time / 2);
$count: floor($count / 2);
.star#{$i}{
$size: #{$i}px;
position: fixed;
width: $size;
height: $size;
border-radius: 50%;
top: 0;
left: 0;
box-shadow: shadowFun($count);
animation: moveUp $time linear infinite;
&::after{
content: '';
position: fixed;
left: 0;
top: 100vh;
width: $size;
height: $size;
border-radius: inherit;
box-shadow: inherit;
}
}
}
- 由于页面上有三个div元素,所以
for
循环三次即可,大家可以改为五次看看更多的效果哦~
在上面这段代码中,会看到额外定义了$time
和$count
两个参数。
$time
:表示每个层级的动画时长,最外层定义了100s
,每一次循环的时候,动画时长就会砍一半,这样就会有不同的层级有不同的动画效果$count
:表示box-shadow
属性中循环的次数,也是每一层级里面星星最大的个数$size
:这里面用了循环体的$i
来表示大小,这样可以看出每个层级的大小不一致,画面会更好看一点。
码上掘金
总结
在sass
的写法中,我们可以看到有很多类似于现在es6
的写法,比如动态元素、for循环,亦或者一些在js中才会出现的处理字符串的方法。
通过这篇文章,主要是告诉大家,css很简单,sass也很简单,当我们写完css代码之后,可以通过js的逻辑思维去思考一下如何可以用sass来简化样式代码。