背景
CSS 自诞生以来,基本语法和核心机制一直没有本质上的变化,在很长一段时间内,它的发展几乎全是表现力层面上的提升。
最开始 CSS 在网页中的作用只是辅助性的装饰,轻便易学是最大的需求;然而如今网站的复杂度已经不可同日而语,原生 CSS 已经让开发者力不从心。
当一门语言的能力不足而用户的运行环境又不支持其它选择的时候,这门语言就会沦为 “编译目标” 语言。开发者将选择另一门更高级的语言来进行开发,然后编译到底层语言以便实际运行。于是,在前端领域,天降大任于斯人也,CSS 预处理器应运而生。
概念
CSS 预处理器是一个能让你通过预处理器自己独有的语法来生成 CSS 的程序。简而言之,最终还是生成CSS代码,但是会让我们书写CSS代码更加方便快速
光看概念还是理解不了,举个栗子
假设现在有这样一个需求摆在我们面前:画一个太阳,画一个太阳肯定不难啊,打开编译器新建文件,开始画太阳
<body>
<div class="sun">
</div>
</body>
太阳应该是一个圆的红的物体,并且周围有光芒,要表示光芒这里就用有颜色的条来代替吧,用光条把太阳围一圈就算是光芒了
<body>
<div class="sun">
<div class="sun-body">
</div>
<div class="sun-light"></div>
<div class="sun-light"></div>
<div class="sun-light"></div>
<div class="sun-light"></div>
<div class="sun-light"></div>
<div class="sun-light"></div>
<div class="sun-light"></div>
<div class="sun-light"></div>
<div class="sun-light"></div>
<div class="sun-light"></div>
<div class="sun-light"></div>
<div class="sun-light"></div>
<div class="sun-light"></div>
<div class="sun-light"></div>
</div>
</body>
然后给它加上样式
<style>
* {
margin: 0;
padding: 0;
}
body {
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
height: 100vh;
background-color: #f1f1f1;
}
.sun {
position: relative;
}
.sun-body {
width: 280px;
height: 280px;
background-color: rgb(243, 94, 26);
border-radius: 50%;
box-shadow: -10px -10px 18px rgba(75, 31, 4, 0.274) inset;
}
</style>
现在可以看到太阳的样子
然后我们再给光条加上样式,旋转让他们围绕太阳
<style>
* {
margin: 0;
padding: 0;
}
body {
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
height: 100vh;
background-color: #f1f1f1;
}
.sun {
position: relative;
}
.sun-body {
width: 280px;
height: 280px;
background-color: rgb(243, 94, 26);
border-radius: 50%;
box-shadow: -10px -10px 18px rgba(75, 31, 4, 0.274) inset;
}
.sun-light {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
width: 40px;
height: 180px;
background-color: rgb(218, 105, 13);
transform: translate(0, -100px) rotate(0deg);
transform-origin: center bottom;
}
.sun-light:nth-of-type(3) {
transform: translate(0, -100px) rotate(30deg);
}
.sun-light:nth-of-type(4) {
transform: translate(0, -100px) rotate(60deg);
}
.sun-light:nth-of-type(5) {
transform: translate(0, -100px) rotate(90deg);
}
.sun-light:nth-of-type(6) {
transform: translate(0, -100px) rotate(120deg);
}
.sun-light:nth-of-type(7) {
transform: translate(0, -100px) rotate(150deg);
}
.sun-light:nth-of-type(8) {
transform: translate(0, -100px) rotate(180deg);
}
.sun-light:nth-of-type(9) {
transform: translate(0, -100px) rotate(210deg);
}
.sun-light:nth-of-type(10) {
transform: translate(0, -100px) rotate(240deg);
}
.sun-light:nth-of-type(11) {
transform: translate(0, -100px) rotate(270deg);
}
.sun-light:nth-of-type(12) {
transform: translate(0, -100px) rotate(300deg);
}
.sun-light:nth-of-type(13) {
transform: translate(0, -100px) rotate(330deg);
}
.sun-light:nth-of-type(14) {
transform: translate(0, -100px) rotate(360deg);
}
</style>
这时候的太阳变成这个样子了
接下来只需要调整一些细节就可以了,当然这里我们目的不在完成需求,重点在于,在画太阳的光条的时候,会出现许多重复的CSS代码
.sun-light:nth-of-type(3) {
transform: translate(0, -100px) rotate(30deg);
}
.sun-light:nth-of-type(4) {
transform: translate(0, -100px) rotate(60deg);
}
.sun-light:nth-of-type(5) {
transform: translate(0, -100px) rotate(90deg);
}
.sun-light:nth-of-type(6) {
transform: translate(0, -100px) rotate(120deg);
}
.sun-light:nth-of-type(7) {
transform: translate(0, -100px) rotate(150deg);
}
.sun-light:nth-of-type(8) {
transform: translate(0, -100px) rotate(180deg);
}
.sun-light:nth-of-type(9) {
transform: translate(0, -100px) rotate(210deg);
}
.sun-light:nth-of-type(10) {
transform: translate(0, -100px) rotate(240deg);
}
.sun-light:nth-of-type(11) {
transform: translate(0, -100px) rotate(270deg);
}
.sun-light:nth-of-type(12) {
transform: translate(0, -100px) rotate(300deg);
}
.sun-light:nth-of-type(13) {
transform: translate(0, -100px) rotate(330deg);
}
.sun-light:nth-of-type(14) {
transform: translate(0, -100px) rotate(360deg);
}
这里仅仅只是每根光条旋转的角度不同,但是我们需要每一条的去写,如果这里有成百上千条,那我们的工作势必会变得重复且繁琐,那么有没有一种办法可以让我们更快更简便的书写CSS代码呢,原生CSS没有,于是,CSS预处理器应运而生
几种具有代表性的预处理器
市面上有很多 CSS 预处理器可供选择,且绝大多数 CSS 预处理器会增加一些原生 CSS 不具备或不完善的高级特性,这些特性让 CSS 的结构更加具有可读性且易于维护。当前社区代表的 CSS 预处理器 主要有以下几种:
1.Sass:2007 年诞生,最早也是最成熟的 CSS 预处理器,拥有 Ruby 社区的支持和 Compass 这一最强大的 CSS 框架,目前受 LESS 影响,已经进化到了全面兼容 CSS 的 SCSS。
2.Less:2009年出现,受 SASS 的影响较大,但又使用 CSS 的语法,让大部分开发者和设计师更容易上手,在 Ruby 社区之外支持者远超过 SASS,其缺点是比起 SASS 来,可编程功能不够,不过优点是简单和兼容 CSS,反过来也影响了 SASS 演变到了 SCSS 的时代,著名的 Twitter Bootstrap 就是采用 LESS 做底层语言的。
3.Stylus:Stylus 是一个CSS的预处理框架,2010 年产生,来自 Node.js 社区,主要用来给 Node 项目进行 CSS 预处理支持,所以 Stylus 是一种新型语言,可以创建健壮的、动态的、富有表现力的 CSS。比较年轻,其本质上做的事情与 SASS/LESS 等类似。
今天我们主要讲sass,因为sass是最早的预处理器,且语法严格,学习完sass再上手其他的预处理器会更加得心应手
学习sass前的准备
在使用sass之前,我们需要进行一些配置,以便编译器可以识别sass语法
打开vscode,找到插件
安装以下几个插件
sass:用于识别sass语法
Easy Sass:用于编译sass文件
Sass Lint:用于格式化sass语法
安装完插件后,在vscode中按住Ctrl+Shift+p键,输入setting,然后选择打开默认设置(JSON)
在编辑器设置中配置Easy Sass
将以下代码直接追加到JSON文件的最后面
"sass.andStared": [
"active",
"focus",
"hover",
"nth-child"
],
"easysass.compileAfterSave": true,
//保存自动编译
"easysass.excludeRegex": "",
"easysass.formats": [
//nested: 嵌套缩进的css代码
//expanded: 没有缩进 扩展的css代码
//compact: 简洁格式的css代码
//compressed: 压缩后的css代码
{
"format": "expanded",
"extension": ".css"
//设置编译输出的文件后缀
},
{
"format": "compressed",
"extension": ".min.css" //设置编译输出的文件后缀
}
],
"easysass.targetDir": "./css/" //提供css输出路径的设置(可以绝对或者相对)
配置代码的最后一行
"easysass.targetDir": "./css/"
指定了编译后CSS文件的输出路径,并且指定的输出路径是一个相对的路径,这是因为在开发中我们通常会创建CSS和Sass两个文件夹,在Sass中书写代码编译后自动输出到CSS文件夹中,为我们省去很多不必要的麻烦
sass常用语法
缩进
因为sass是由Ruby语言开发的,所以直接继承了它的语法,即缩进式语法
*
margin: 0
padding: 0
body
background-color: #111
.header
background-color: #333
.wrap
background-color: #984532
div
background-color: #699654
编译生成的CSS文件如下
* {
margin: 0;
padding: 0;
}
body {
background-color: #111;
}
body .header {
background-color: #333;
}
body .header .wrap {
background-color: #984532;
}
body .header .wrap div {
background-color: #699654;
}
sass严格的缩进使它的语法十分严格,这里还有一个特殊符号,可以让我们回到上一级的选择器进行书写代码
*
margin: 0
padding: 0
body
background-color: #111
.header
background-color: #333
.wrap
background-color: #984532
&
background-color: #699654
div
background-color: #699654
CSS
* {
margin: 0;
padding: 0;
}
body {
background-color: #111;
}
body .header {
background-color: #333;
}
body .header .wrap {
background-color: #984532;
}
body .header .wrap {
background-color: #699654;
}
body .header .wrap div {
background-color: #699654;
}
可以看到在.wrap选择器下一层中使用&则书写的代码就是在.wrap这一层作用的
&在这里代表父级的选择器,但是要注意&最多只能往上回溯一层,如果多于一层就需要另外写了
变量
我们可以采用以$开头命名的标识符作为变量保存一些固定的值,然后在书写样式的时候用上,比如这里我们将一些样式中需要常用到的用变量保存起来,这样我们突然改需求就可以直接更改变量的值了
$backgroundcolor: #222
$margin: 10px 20px 20px 10px
$barry: 20px
body
background-color: $backgroundcolor
width: 100px
height: $barry
.wrap
width: 100px
height: 20px
保存编译后,查看生成的CSS文件
body {
background-color: #222;
width: 100px;
height: 20px;
}
body .wrap {
width: 100px;
height: 20px;
}
如果变量需要镶嵌在字符串之中,就必须需要写在#{}之中。
$side: left
.rounded
border-#{$side}-radius: 5px
简单运算
我们还可以在样式中进行一些简单的运算,如加减乘除
$backgroundcolor: #222
$margin: 10px 20px 20px 10px
$barry: 20px
body
background-color: $backgroundcolor
width: 100px
height: $barry
.wrap
width: 80px + $barry
height: 20px
margin: 10px + $barry 40px - $barry $barry * 1 $barry / 10
CSS
body {
background-color: #222;
width: 100px;
height: 20px;
}
body .wrap {
width: 100px;
height: 20px;
margin: 30px 20px 20px 2px;
}
可以看到简易的加减乘除都实现了
条件语句
sass中也有条件语句,可以根据一些条件来决定是否书写代码,逻辑和编程语言中是一样的
$name: 张三
body
width: 100px
@if $name == 张三
height: 100px
@else
height: 200px
当$name是等于张三的时候,生成的CSS文件如下
body {
width: 100px;
height: 100px;
}
当$name不等于张三的时候,生成CSS文件如下
body {
width: 100px;
height: 200px;
}
嵌套
sass允许选择器的嵌套,如下面的css代码
div h1 {
color: red;
}
可以用sass写成
div
h1
color: red
循环
在sass中我们可以书写循环,很方便的书写多行重复性的代码
$color-list: #354, #754, #198, #203, #675
@each $color in $color-list
$i: index($color-list,$color)
li:nth-of-type(#{$i})
background-color: $color
@if $i <= 4
height: 120px
@else
height: 80px
生成的CSS文件
li:nth-of-type(1) {
background-color: #354;
height: 120px;
}
li:nth-of-type(2) {
background-color: #754;
height: 120px;
}
li:nth-of-type(3) {
background-color: #198;
height: 120px;
}
li:nth-of-type(4) {
background-color: #203;
height: 120px;
}
li:nth-of-type(5) {
background-color: #675;
height: 80px;
}
这里还采用了index()方法,可以从数组中找到值的下标,前面传参数组,后面传查找的元素
同时在循环中还有条件语句,决定height的渲染大小
代码的重用
mixin
mixin可以说是sass的一大臂膀之一
混合指令(Mixin)用于定义可重复使用的样式,避免了使用无语意的 class,比如 .float-left。混合指令可以包含所有的 CSS 规则,绝大部分 Sass 规则,甚至通过参数功能引入变量,输出多样化的样式。
简而言之,mixin就是一个代码块,里面封装的是可用性很高的样式代码,同时还能通过传参来改变值
@mixin sethw($h: 100px, $w: 200px)
height: $h
width: $w
body
background-color: #345
@include sethw(400px, 800px)
.wrap
@include sethw(200px)
.div
@include sethw(450px, 230px)
生成的CSS文件
body {
background-color: #345;
height: 400px;
width: 800px;
}
body .wrap {
height: 200px;
width: 200px;
}
body .wrap .div {
height: 450px;
width: 230px;
}
可以看到,在不同的传参中,最后生成的CSS文件就是不同的,而这也是mixin的好处,可以将那些复用性极高的样式封装起来,同时在mixin中我们也可以使用条件,循环之类的语句
继承
sass允许一个选择器去继承另一个选择器
.class1
border: 1px solid #ddd
class2继承class1,需要在class2中使用@extend命令
.class2
@extend .class1
font-size: 120%
最后生成的css代码如下
.class1, .class2 {
border: 1px solid #ddd;
}
.class2 {
font-size: 120%;
}
注释
SASS共有两种注释风格。
1.标准的CSS注释 /* comment */ ,会保留到编译后的文件。
2.单行注释 // comment,只保留在SASS源文件中,编译后被省略。
在/*后面加一个感叹号,表示这是"重要注释"。即使是压缩模式编译,也会保留这行注释,通常可以用于声明版权信息。
例
/*!
重要注释!
*/
颜色函数
SASS提供了一些内置的颜色函数,以便生成系列颜色。
lighten(#cc3, 10%)//#d6d65c通过改变颜色的亮度值(0%-100%),让颜色变亮,创建一个新的颜色
darken(#cc3,10%)//#a3a329通过改变颜色的亮度值(0%-100%),让颜色变暗,创建一个新的颜色
grayscale(#cc3)//#808080将一个颜色变成灰色
complement(#cc3)//#33c返回一个补充色
插入文件
@import命令,用来插入外部文件
@import path/filename;
如果插入的是.css文件,则等同于css的import命令
@import "foo.css";
有关sass的语法这些我们可以到sass中文网查看文档
还有其他的预处理器,学会sass之后,就很容易上手了
我是程序员云锦,下次再见!