吃土也要学完的sass真是太强大了
一、Sass的安装
由于Sass是使用Ruby编写的,所以我们在使用Sass之前需要安装一下Ruby。下面是Windows平台的安装步骤。对于Mac平台,请查看这里: Mac平台安装Sass 。
【步骤1“下载Ruby”】:大家到Ruby的官网( http:// rubyinstaller.org/downl oads )下载最新版本的Ruby版本,这里我们下载的是“Ruby2.3.1”。
编辑
【步骤2“安装Ruby”】:下载好“Ruby2.3.1”之后,点击安装即可。在安装的时候,我们需要注意2点:(1)安装路径建议选择C盘;(2)安装到下面这一步时,一定一定要选择第2项,不然就会安装失败:
编辑
【步骤3“下载Sass”】:安装好“Ruby2.3.1”之后,然后到这个页面( https:// rubygems.org/gems/sass )上面把“Sass安装包”下载下来。我们可以在这个网页右栏找到“下载”这两个字,点击即可下载:
编辑
【步骤4“打开Ruby命令端”】:在电脑的左下方点击“开始”→“所有程序”→“Ruby 2.3.1” →“Start Command Prompt with Ruby”:
编辑
【步骤5】:打开Ruby命令终端之后,输入下面这个指令,把Sass安装包拖到命令指定位置会生成指定路径,然后点击“Enter回车”即可安装,如图所示:
gem install <这里把Sass安装包拖进来>
编辑
【步骤6】:上面的步骤都完成后,我们需要检查Sass是否安装成功。检查的方法很简单,我们在命令终端使用“sass -v”指令,按回车后,如果显示“Sass 3.4.22 <Selective Steve>”的字样就说明Sass安装成功:
编辑
二、Sass的更新
Sass版本会不断更新,不过更新Sass并不需要像其他软件那样每次更新都需要卸载,然后再重装。在Sass中,每次更新版本,我们只需要在命令终端输入一个指令即可:
gem update sass
点击“Enter”键后,如果显示下图信息“Nothing to update”,说明Sass已经更新到最新版本了:
编辑
三、Sass的卸载
在使用Sass的过程中,有时候我们会碰到一些无法解决的问题,这个时候就需要卸载Sass再重新安装Sass了。在Sass中,每次卸载,我们也只需要一个指令就能解决:
gem uninstall sass
输入命令,点击“Enter”键后,就能卸载Sass了。不过一般情况下,我们是用不着卸载这个指令的。
sass简介
一、什么是CSS预处理器?
学过CSS的小伙伴都知道,CSS只是一门描述性的语言,你只能一行一行单纯地描述,并不能像JavaScript那样使用变量、循环、运算等方式来操作。
CSS预处理器的出现,使得我们可以像操作JavaScript那样以“编程”的方式来书写CSS。在CSS预处理器中,我们可以使用变量、循环、函数等方式来简化操作,提高开发效率。说得一点都没错,现在写CSS也可以这么爽了。小伙伴们看到这里,必须大吃一惊:“我out了!”
CSS预处理器,这个术语真专业……不过坑爹的术语,往往都是吓唬人的,实际并不难。CSS预处理器,说白了就是用编程方式来写CSS的一类语言,就这么简单。
CSS预处理器语言有很多,最常见的有3种:
- (1)Sass;
- (2)Less;
- (3)Stylus;
这些CSS预处理语言都具备编程的特性,这种编程方式相对于纯CSS书写方式来说,具有更加简洁、适应性更强、可读性更佳、更易于代码的维护等优点。
二、什么是Sass?
Sass是功能最为强大、最成熟、并且是最为流行的CSS预处理器。因此,对于Sass、Less和Stylus这3个,我们还是建议大家学习Sass。
Sass是一种动态样式语言,比CSS多出好些功能(如变量、嵌套、运算、混入、继承、颜色处理、函数等),更容易阅读。
在学习Sass之前,我们需要一定的HTML、CSS和JavaScript基础,以下是先修课程:
(1) HTML入门教程
(2) CSS入门教程
(3) JavaScript入门教程
想要深入学习Sass的小伙伴,也可以到Sass官网看看: Sass官方文档 。
三、Sass和Less
Sass和Less是当下最为流行的2门CSS预处理语言,也是国内外讨论最热的2个。很多小伙伴在刚刚接触的时候,总是纠结学哪一门好点。这一节,我们来给大家介绍一下Sass和Less的区别。
Sass和Less差别不大,语法也相近。不管是Sass,还是Less,都可以视为一种基于CSS之上的高级语言,其目的都是为了让CSS开发更为灵活和更强大。但是两者也有以下明显区别:
- (1)Sass由于是使用Ruby编写的,所以编译的时候是在服务器端处理;而Less由于是使用JavaScript编写的,所以编译的时候是在浏览器端处理;
- (2)Sass拥有更为强大的功能,如循环、函数、混合宏等,而less却没有;
- (3)Sass拥有成熟稳定的框架来辅助开发,特别是Compass,而less却没有;
- (4)Sass在国内外讨论热度最大,并且有一个稳定强大的团队在维护;
- (5)相当多的公司更为倾向于使用Sass,而不是less;
简单来说,Sass是比less更为强大并且使用更广的一门CSS预处理器语言。在实际开发中,如果你只是单纯地想简化CSS写法、统一风格、增强维护性的话,那么Sass和Less是一样的,学习哪一个都可以。
但是如果想要用到更多并且更加强大的功能的话,那么你应该选择Sass。在这里,我也强烈建议小伙伴们学习的是Sass,而不是Less。Sass最强大之处是配合Compass来辅助CSS开发。其中,Compass是在Sass的一个框架,保证让你爽到爆。对于Compass,别忘了关注即将上线的Compass教程。
四、Sass和Scss
在Sass中,有2种语法格式:(1)Sass格式;(2)Scss格式。也就是说,平常我们所说的Sass和Scss其实是同一个东西来的,统称为Sass。Sass和Scss仅仅是Sass的两种语法格式罢了。
Sass格式
Sass格式,是Sass的“旧版本语法”。这种语法格式,不使用大括号“{}”和分号“;”,而是使用严格的缩进式语法规则来书写,也就是类似Ruby语言的写法。
举例:
$color:white $bgColor:red body color:$color background-color:$bgColor
从这里我们可以看出,Sass格式是不使用大括号“{}”和分号“;”的,并且在body元素定义样式的时候,color和background-color这2个属性都是严格缩进的。说明:
Scss格式
Scss格式,是Sass的“新版本语法”。这种语法格式,使用大括号“{}”和分号“;”,并不使用严格的缩进式语法规则来书写,也就是类似CSS书写的格式。
举例:
$color:white $bgColor:red body { color:$color background-color:$bgColor }
从这里我们可以看出,Scss格式跟平常我们写CSS的格式是一样的。
变量
在JavaScript中,声明变量都是用var。但是在Sass中,我们声明变量使用的是“$”(美元符号)开头。
语法:
编辑
说明:
我们可以看出,Sass的变量包括3部分:声明符、变量名、值。Sass变量定义的方式,跟CSS语法很相似,这个我们很容易理解。此外我们需要注意一下,定义一个Sass变量必须用“$”开头,不然编译的时候是无法识别的。
在Sass中,对于变量的取值有2种方式:(1)一般值;(2)默认值。
1、一般值
在Sass中,变量的一般值,指的是我们常见的变量值,这个值可以是数字、字符串等。
举例1:
$width:10px; div { font-size:$width; }
编译出来的CSS代码如下:
div { font-size:10px; }
举例2:
$color:white; $bgColor:red; body { color:$color; background-color:$bgColor; }
编译出来的CSS代码如下:
body { color:white; background-color:red; }
2、默认值
在Sass中,变量还有一种取值方式,那就是默认值。所谓的默认值,指的是给变量初始化一个默认值,这个值在后面可以根据开发的需要,使用一个“同名变量”的值覆盖掉。定义变量的默认值很简单,我们只需要在“变量值”后面加上“!default”就可以了。
举例:
$width:10px !default; .div1 { width:$width; } .div2 { $width:20px; width:$width; } .div3 { $width:30px; width:$width; }
编译出来的CSS代码如下:
.div1 { width:10px; } .div2 { width:20px; } .div3 { width:30px; }
分析:
想要覆盖变量的默认值很简单,我们只需要在该变量被调用之前重新定义该变量的值就可以了。变量的默认值,在实际开发特别是组件化开发中是非常有用的。当然,这里我们只需要简单了解一下即可。
二、变量的作用域
跟JavaScript的变量一样,Sass的变量也有作用域。在Sass中,变量根据作用域可以分为2种:(1)全局变量;(2)局部变量。
其中,Sass中的作用域跟JavaScript中的作用域是非常相似的。
1、全局变量
在Sass中,全局变量一般指的是在“选择器、混合宏、继承等”外部定义的变量。全局变量从定义开始,一直到整个程序结束都起作用。对于混合宏、继承这些,我们在后续章节会详细介绍。
举例:
$color:red; //定义全局变量 body { color:$color; //调用全局变量 }
编译出来的CSS代码如下:
body { color:red; }
2、局部变量
在Sass中,局部变量一般指的是在“选择器、混合宏、继承等”内部定义的变量。局部变量只能在这些的内部起作用,在这些的外部是不起作用的。
举例:
$color:red; //定义全局变量 body { $color:green; //定义局部变量 div { color:$color; //调用局部变量 } }
编译出来的CSS代码如下:
body { color:green; }
分析:
在这个例子中,局部变量“$color:green;”会把全局变量“$color:red;”的值覆盖,因此最终$color的值是green。对于这个,我们联系一下JavaScript中的局部变量和全局变量就不难理解了。
数据类型
跟JavaScript一样,Sass也有属于自己的数据类型。在Sass中,共有7种数据类型:
- (1)数字值;
- (2)字符串;
- (3)布尔值;
- (4)颜色值;
- (5)列表值;
- (6)Map值;
- (7)空值null;
接下来,我们在这一节详细介绍一下Sass种的7种数据类型。
一、数字值
在Sass中,数字(Number)是最基本的数据类型,可以是正数、0或负数。数字在Sass中使用非常广泛,大多数都是结合CSS单位来实现的,例如10px、10em或者10%。虽然它们带有单位,但是技术上依然算是数字。
举例:
$lineHeight:1.5; $fontSize:14px; $width:50%; div { lineHeight:$lineHeight; font-size:$fontSize; width:$width; }
编译出来的CSS代码如下:
div { line-height:1.5; font-size:14px; width:50%; }
二、字符串
在JavaScript中,使用单引号('')或双引号("")包含的都是字符串,就算它们包含的是一个空格,那也是字符串。但是Sass中的字符串跟JavaScript中的字符串有点不一样。
在Sass中,共有2种字符串:
- (1)有引号的字符串;
- (2)无引号的字符串;
无引号字符串,我们在CSS中是经常遇到的,例如“font-weight:bold”中的bold、“font-family:sans-serif;”中的sans-serif等。Sass引入无引号字符串的目的也是为了与CSS语法一致。
举例:有引号字符串
$logoUrl: "images/logo.png"; $cursorUrl: "images/default.cur"; $text:"绿叶学习网"; div { background-image:url($logoUrl); cursor:url($cursorUrl),default; } div:before { content:$text; }
编译出来的CSS代码如下:
div { background-image:url("images/logo.png"); cursor:url("images/default.cur"),default; } div:before { content:"绿叶学习网"; }
举例:无引号字符串
$str1:sans-serif; $str2:bold; div { font-family:$str1; font-weight:$str2; }
编译出来的CSS代码如下:
div { font-family: sans-serif; font-weight: bold; }
三、布尔值
数字值和字符串这2种数据类型的取值有无数种,但是Sass中的布尔值只有2种取值:true和false。
在Sass中,布尔值一般用于“@if…@esle…语句”条件判断,只有条件表达式结果是false或null才会返回false,其他一切将返回true。
举例:无引号字符串
$a:10px; $b:5px; div { @if($a>$b) { display:block; } @else { ; } }
编译出来的CSS代码如下:
div { display:block; }
分析:
Sass中的“@if...@else...”跟JavaScript中的“if...else...”是一样的,这个语句我们在后面“Sass @if语句”这一节中会详细介绍。
在这个例子中,($a>$b)返回的是true,所以div的display属性最终取值为block。
四、颜色值
在Sass,有一种特殊的数据类型,那就是“颜色值”。Sass中的颜色值共有4种:
- (1)关键字颜色值,如red;
- (2)十六进制颜色值,如#FFFF00;
- (3)RGB颜色值,如rgb(255,255,0);
- (4)HSL颜色值,如;hsl(360,50%,50%);
这几种颜色值都是可以互相转换的,在Sass的颜色运算中,我们都是统一转换为十六进制颜色值然后再计算。对于“Sass颜色运算”,我们在后面章节会详细介绍。
举例:
$fontColor:#FF00FF; $bgColor:blue; div { color:$fontColor; background-color:$bgColor; }
编译出来的CSS代码如下:
div { color: red; background-color: #FF00FF; }
五、列表值
在Sass中,为我们提供了一种“列表值”的数据类型,这种数据类型跟JavaScript中的数组是相似的,我们可以把它比作“Sass中的数组”。
Sass列表值有2种语法格式,一种是由英文逗号隔开的分隔值,另外一种是由空格隔开的分隔值。
语法:
$列表名: 值1 , 值2 , ... , 值n; $列表名: 值1 值2 ... 值n;
说明:
在Sass中,列表值可以包含0个、1个或多个值,甚至还可以包含多个“子列表值”。Sass中的列表值,往往都是用来处理CSS中类似于以下的属性取值:
margin:10px 20px 30px 40px; padding:10px 20px 30px 40px; font-family:Microsoft YaHei,Arial,Helvetica,sans-serif;
举例:
$font: Arial,Helvetica,sans-serif; $margin:20px 40px; $border:1px solid gray; div { font:$font; margin:$margin; border:$border; }
编译出来的CSS代码如下:
div { font: Arial, Helvetica, sans-serif; margin: 20px 40px; border: 1px solid gray; }
分析:
对于列表值,Sass为我们提供了很多内置的函数,在后面“Sass列表函数”这一章我们会详细介绍。这里我们只需要简单认识一下就可以了。
六、Map值
在Sass中,还为我们提供了另外一种特殊数据类型:Map值。Map值跟JSON值是非常相似的,数据都是以“键/值”的方式成对出现。
语法:
$变量名: ( 键名1:值1, 键名2:值2, …… 键名n:值n );
说明:
Map值的语法结构都是以“(”开始,到“)”结束的。其中“键名”和“值”之间用英文冒号构成对,两个“键名:值”之间用英文逗号分隔。此外还要注意一下,最后一对“键/值”后面是不需要逗号的。
举例:
$theme-color: ( default: ( bgcolor: #fff, text-color: #444, link-color: #39f ), primary: ( bgcolor: #000, text-color:#fff, link-color: #93f ), negative: ( bgcolor: #f36, text-color: #fefefe, link-color: #d4e ) );
分析:
对于Map值,Sass为我们提供了很多内置的函数,在后面“Sass Map函数”这一章我们会详细介绍。这里小伙伴们不需要深入了解Map值,只需要简单认识一下就可以了。
嵌套
Sass为我们提供了一种方便的操作方式:嵌套。在Sass中,共有3种嵌套方式:
- (1)选择器嵌套;
- (2)属性嵌套;
- (3)伪类嵌套;
一、选择器嵌套
选择器嵌套,是Sass中最常见的嵌套方式,这个类似于HTML元素的嵌套。这种嵌套方式我们在之前的章节接触过好几次了,现在再来看一个复杂点的例子。
举例:
$color1:red; $color2:green; $color3:blue; body { color:$color1; .column { color:$color2; .content-title { color:$color3; } } }
编译出来的CSS代码如下:
body { color: red; } body .column { color: green; } body .column .content-title { color: blue; }
分析:
选择器嵌套这种方式虽然操作起来很方便,但是却有一个很大的弊端:嵌套的层级越深,编译出来的CSS代码的选择器层级也越深。这种嵌套方式会导致CSS样式冗余,并且难以维护。
在CSS中,选择器的层级越多,浏览器解析时匹配的次数就越多,因而速度就越慢。因此在定义选择器的时候,我们要尽量让选择器的层级少一些,最好不要超过3层。所以在实际开发中,我们应该尽量注意一下Sass选择器嵌套中的层级问题,尽量少用选择器嵌套的方式来书写Sass。
二、属性嵌套
在Sass中,还为我们提供了一种属性嵌套的方式。我们都知道,CSS有些属性的前缀是相同的,例如:
- (1)border-top、border-right、border-bottom、border-left这4个属性拥有相同的前缀“border”;
- (2)margin-top、margin-right、margin-bottom、margin-left这4个属性拥有相同的前缀“margin”;
- (3)font-family、font-size、font-weight、font-variant等属性拥有相同的前缀“font”;
- ……
对于这些拥有相同前缀的属性,我们可以使用属性嵌套的方式来简化操作。
举例:
div { width:100px; height:100px; font: { family:Arial; size:14px; weight:bold; } }
编译出来的CSS代码如下:
div { width: 100px; height: 100px; font-family: Arial; font-size: 14px; font-weight: bold; }
分析:
对于属性嵌套,我们要特别注意一点:在需要嵌套的属性前缀后面一定要加英文冒号“:”,不然编译出来的就不是我们想要的效果。
在上面例子中,如果我们把font后面的冒号去掉,编译出来的CSS代码如下:
div { width: 100px; height: 100px; } div font { family: Arial; size: 14px; weight: bold; }
这就完全不是我们预期的效果了。刚刚接触Sass的小伙伴们一定要特别留意这一点。
举例:
div { border: { top:1px solid red; bottom:1px solid green; } }
编译出来的CSS代码如下:
div { border-top: 1px solid red; border-bottom: 1px solid green; }
三、伪类嵌套或伪元素嵌套
在Sass中,还有一种嵌套方式:伪类嵌套或伪元素嵌套。伪类嵌套(或伪元素嵌套)跟属性嵌套很像,只不过它是需要借助“&”符号一起配合使用。
对于伪类,我们在“ CSS入门教程 ”中的 “ CSS超链接伪类 ”接触过了。CSS3也增加很多伪类,如:first-child、nth-child()等。
伪元素跟伪类是不一样的,常见的伪元素只有4个,即::before、::after、::first-letter、::first-line。对于伪元素和伪类的区别,具体请参考“ CSS3教程 ”进阶部分(即将上线)。
举例:伪类嵌套
$color1:red; $color2:green; a{ color:$color1; &:hover { color:$color2; } }
编译出来的CSS代码如下:
a { color: red; } a:hover { color: green; }
分析:
伪类嵌套都是结合“&”符号来实现的,编译的时候“&”会替换成相应的选择器。
举例:伪元素嵌套
.clearfix { *zoom:1; &:after { clear:both; content:""; display:block; height:0; ; } }
编译出来的CSS代码如下:
.clearfix{*zoom:1;} .clearfix::after { clear:both; content:""; display:block; height:0; ; }
分析:
伪元素嵌套同样也是结合“&”符号来实现的,编译的时候“&”会替换成相应的选择器。上面这个是清除浮动最常用的方法,具体原理可以参 css float浮动
Sass插值实例讲解
在Sass中,我们可以通过使用插值的方式来实现在“选择器名”、“属性名”以及“属性值”中插入一个“变量的值”,从而来“构造”一个新的选择器名、新的属性名以及新的属性值。
语法:
#{变量}
说明:
插值这种方式,在Sass代码的几乎任何一个地方都可以插入一个值,包括选择器名、属性名、属性值等。我们还是来个例子比较直观一点。
举例1:插值用于“选择器名”
@for $i from 1 through 3 { .item-#{$i} { width:10px * $i; } }
编译出来的CSS代码如下:
.item-1 { width: 10px; } .item-2 { width: 20px; } .item-3 { width: 30px; }
分析:
“@for $i from 1 through 3”很好理解,这表示一个从1到3的循环,在后面“Sass @for循环”这一节我们会详细介绍。
细心的小伙伴们可能就有疑问了,我直接用下面这种插入变量的方式,不也能实现吗?
@for $i from 1 through 3 { .item-$i { width:10px * $i; } }
不好意思,还真不能!变量,我们一般都是用于属性值的,是不能直接用于选择器名中的,不然Sass会无法编译成CSS。
举例:插值用于“属性名”
$border:border; div { #{$border}-width:1px; #{$border}-style:solid; #{$border}-color:red; }
编译出来的CSS代码如下:
div { border-width: 1px; border-style: solid; border-color: red; }
分析:
由于变量只能用于属性值,是不能直接用于属性名的,也就是说如果我们使用下面这种方式是达不到预期效果的:
$border:border; div { $border-width:1px; $border-style:solid; $border-color:red; }
举例:插值用于“属性值”
@for $i from 1 through 3 { .item-#{$i} { border:#{$i}px solid red; } }
编译出来的CSS代码如下:
.item-1 { border: 1px solid red; } .item-2 { border: 2px solid red; } .item-3 { border: 3px solid red; }
分析:
在这个例子中,如果我们用以下方式,也是达不到我们预期效果的:
@for $i from 1 through 3 { .item-#{$i} { border:$ipx solid red; } }
这是因为border属性的属性值是一个列表值,而不是单纯的一个数字或字符串。也就是说,如果属性值是一个简单数字或者字符串,我们可以使用变量的方式来实现。但如果属性值是一个复杂的数据类型,我们就必须使用插值的方式来实现。
总而言之,如果你想要在Sass中构造一个新的选择器名、新的属性名以及新的属性值,首先考虑的应该是使用“插值#{}”来实现。
实现Sass注释的三种方式
一、//注释内容
在Sass中,这种注释方式在编译后不会保留下来。
举例:
$height:20px; body { //height和line-height值相等,实现单行文字垂直居中 height:$height; line-height:$height; }
编译出来的CSS代码如下:
body { height: 20px; line-height: 20px; }
二、/*注释内容*/
在Sass中,这种注释方式在编译之后会保留下来。因为这种注释方式跟CSS注释方式是相同的,所以编译后会保留下来。
举例:
$height:20px; body { /*height和line-height值相等,实现单行文字垂直居中*/ height:$height; line-height:$height; }
编译出来的CSS代码如下:
body { /*height和line-height值相等,实现单行文字垂直居中*/ height: 20px; line-height: 20px; }
分析:
我们可以看出,在Sass中使用“/*注释内容*/”这种方式,编译出来的CSS也会保留其注释。
三、/*!注释内容*/
我们都知道压缩工具会删除所有的注释,有些时候为了保留一些版权声明的注释说明,可以采用以下方式:
/*!注释内容*/
也就是说在注释内容前面加上一个“!”,这种压缩工具就不会删除这条注释信息了。不过这种注释方式用得很少,一般在CSS文件顶部为了声明版权信息才会使用。
举例:
/*!Copyright ©2015-2017 www.lvyestudy.com, All Rights Reserved*/ $height:20px; body { height:$height; line-height:$height; }
编译出来的CSS代码如下:
/*!Copyright ©2015-2017 www.lvyestudy.com, All Rights Reserved*/ body { height: 20px; line-height: 20px; }
sass基本运算
我们都知道,在CSS中能做运算的,也只有cal()函数这一个。不过Sass是一门“编程”式的语言,它为我们提供了类似于JavaScript的各种运算方式,例如加、减、乘、除等。
在Sass中,共有3种运算情况:
- (1)数字运算;
- (2)字符运算;
- (3)颜色运算;
接下来,我们一一给大家详细介绍。
第一种数字运算
在Sass中,共有4种数字运算:
- (1)加法;
- (2)减法;
- (3)乘法;
- (4)除法;
这4种运算方式,我们在其他编程语言(如JavaScript)也能看到,但是Sass的这4种运算不太一样,还是有不少我们需要注意的地方。所以在这一节中,小伙伴们要细心留意一下。
一、Sass加法
在Sass中,做加法运算时,数值可以带单位,但是需要运算单位相同。如果不相同就会报错,编译不通过。
举例1:运算单位相同
div { width:(100px + 20px); }
编译出来的CSS代码如下:
div { width:120px; }
分析:
由于“100px”和“20px”的单位相同,都是px。所以在Sass中,这两个可以做加法运算。
举例2:运算单位不同
div { width:(100px + 20em); }
编译出来的CSS代码如下:
Incompatible units: 'em' and 'px'.
分析:
因为“100px”和“20em”单位不同,所以在Sass编译的时候会报错。其中,“Incompatible units: 'em' and 'px'.”意思是“em和px单位不一致”。
我们再来看一个实际开发中的例子,体会一下Sass加法的用法:
$sidebar-width:220px; $content-width:720px; $gap-width:20px; .container { width: ($sidebar-width + $content-width + $gap-width) margin: 0 auto; }
编译出来的CSS代码如下:
.container { width:960px; margin:0 auto; }
二、Sass减法
在Sass中,做减法运算时,数值可以带单位,但是需要运算单位相同。如果不相同就会报错,编译不通过。这一点跟Sass加法是一样的。
举例1:运算单位相同
div { width:(100px - 20px); }
编译出来的CSS代码如下:
div { width:80px; }
分析:
由于“100px”和“20px”的单位相同,都是px。所以在Sass中,这两个可以做减法运算。
举例2:运算单位不同
div { width:(100px - 20em); }
编译出来的CSS代码如下:
Incompatible units: 'em' and 'px'.
分析:
因为“100px”和“20em”单位不同,所以在Sass编译的时候会报错。其中,“Incompatible units: 'em' and 'px'.”意思是“em和px单位不一致”。
我们也来看一个实际开发中的例子,体会一下Sass减法的用法:
$container-width:960px; $sidebar-width:200px; .content { width: ($container-width - $sidebar-width); }
编译出来的CSS代码如下:
.content { width:760px; }
分析:
在Sass中,如果是做减法运算是“变量”而不是“数值”的时候,我们要注意减号“-”前后一定要有空格。像上面这个例子,如果减号前后没有空格:
$container-width:960px; $sidebar-width:200px; .content { width: ($container-width-$sidebar-width); }
像上面这样,Sass是无法正确地识别哪个“-”是变量的一部分,哪个“-”是减号。不过对于Sass中的加法,则不需要考虑这一点。
三、Sass乘法
在Sass中,做乘法运算时,只能有一个数值带单位,另外一个数值只能是不带单位的数字。如果两个都是带单位的数字,则Sass会报错而编译不通过。其实,小伙伴们稍微想一下平常数学中的运算,就很容易明白。
举例1:一个带单位,另外一个不带单位
div { width:(100px * 2); }
编译出来的CSS代码如下:
div { width:200px; }
举例2:两个都带单位
div { width:(100px * 2px); }
编译出来的CSS代码如下:
200px*px isn't a valid CSS value.
分析:
“200px*px isn't a valid CSS value.”意思是:200px*px不是一个有效的CSS属性值。我们再来看一个实际开发中的例子,体会一下Sass乘法的用法:
@for $i from 1 through 3 { .item-#{$i} { width:10px * $i; } }
编译出来的CSS代码如下:
.item-1 { width: 10px; } .item-2 { width: 20px; } .item-3 { width: 30px; }
四、Sass除法
我们都知道,“/”在CSS中已经作为一种符号来使用了,例如我们常见的字体属性缩写“font:Arial 12px/1.5em”。因此在Sass中做除法运算的时候,如果我们直接使用“/”符号作为除号,将不会生效。
在Sass中,如果我们想要做除法运算,我们需要在外面添加一个“小括号()”。
举例:
div { width:(100px/2); }
编译出来的CSS代码如下:
div { width:50px; }
分析:
在这个例子中,如果我们将小括号去掉,则Sass编译的时候会报错。但是在Sass中,如果做除法运算中是“变量”而不是“数值”时,“/”会被自动识别为除法,不需要在外面添加小括号。
举例:
$width:100px; div { width:$width/2; }
编译出来的CSS代码如下:
div { width:50px; }
在使用Sass的过程中,“/”这个符号被当做除法运算时有以下3种情况:
- (1)数值被小括号()包含;
- (2)数值是另外一个数学表达式的一部分;
- (3)数值或它的任意部分存储在一个变量中或者函数的返回值;
举例:
$height:100px; div { font:20px/10px; //纯CSS,不是除法运算 width:(20px/10px); //使用了小括号,是除法运算,符合第1点 height:$height/2; //使用了变量,是除法运算,符合第3点 line-height:round(1.5)/2; //使用了函数,是除法运算,符合第3点 margin-left:10px + 10px/2px; //使用了加号,是除法运算,符合第2点 }
编译出来的CSS代码如下:
div { font: 20px/10px; width: 2; height: 50px; line-height: 1; margin-left: 15px; }
分析:
在实际开发中,不管是加法、减法,还是乘法、除法运算,我们都建议在外面加上小括号。这种书写方式,能够使得代码一目了然,也方便维护。希望小伙伴们也规范一下自己的书写方式。
字符运算
在之前“ Sass数据类型 ”这一节我们知道,CSS有2种字符串类型:(1)有引号字符串;(2)无引号字符串。
在Sass中,我们可以使用“+”(加号)来实现字符串的拼接。对于字符串的连接,我们分为3种情况来考虑:
- (1)如果左右两个字符串都是有引号的,结果是一个有引号的字符串;
- (2)如果左边字符串是有引号的,右边字符串是没有引号的,结果是一个有引号的字符串;
- (3)如果左边字符串是没有引号的,右边字符串是有引号的,结果是一个没有引号的字符串;
一句话概括:结果字符串是否有引号,取决于左边字符串是否有引号。
举例:
div::before { content: "Welcome to " + lvyestudy; font:sans- + "serif"; }
编译出来的CSS代码如下:
div:before { content: "Welcome to lvyestudy"; font: sans-serif; }
分析:
Sass之所以会引入2种字符串,也是为了与CSS的语法一致。
颜色运算
颜色值是Sass中的一种特殊的数据类型,我们在之前“ Sass数据类型 ”这一节已经详细介绍过了。
在Sass中,我们也是可以对颜色值进行运算的。颜色运算支持加、减、乘、除,并且是分段进行计算的。也就是说,红、绿、蓝这3个部分的颜色是单独进行计算的。
举例1:
div { color: (#010203 + #040506); }
编译出来的CSS代码如下:
div { color: #050709; }
分析:
由于颜色运算是分段的,其中红、绿、蓝3个部分单独进行计算,所以这个例子的计算方式为:
01 + 04=05, 02 + 05=07, 03 + 06=09
最后,将这3段计算后的结果合并得到最终颜色值:#050709。
举例2:
div { color: (#010203 * 2); }
编译出来的CSS代码如下:
div { color: #020406; }
分析:
由于颜色运算是分段的,其中红、绿、蓝3个部分单独进行计算,所以这个例子的计算方式为:
01 * 2=02, 02 * 2=04, 03 * 2=06
最后,将这3段计算后的结果合并得到最终颜色值:#020406。
此外,如果颜色值不是十六进制颜色值(如#010203),而是RGB或者HSL的话,我们都是将RGB或HSL先转换为十六进制颜色值,然后再进行加、减、乘、除运算的。
div { color:(rgb(17,34,51) *2); }
编译出来的CSS代码如下:
div { color: #224466; }
分析:rgb(17,34,51转化为十六进制颜色值为“#112233”,然后进行乘法运算,最后得到最终颜色值:#224466。
Sass代码重用
在实际开发中,我们经常会碰到好些不同地方都用到相同的CSS样式的情况。如果相同的CSS样式只有一个CSS属性,此时只需要使用Sass变量实现就可以满足了。如果相同的CSS样式有多个CSS属性,这个时候我们就希望把“相同的CSS样式”当做整块来处理。
在Sass中,为我们提供了3种方式来处理经常被多个地方使用的相同的CSS代码块:
- (1)继承“@extend”;
- (2)占位符“%placeholder”;
- (3)混合宏“@mixin”;
这几种实现代码重用的方式,在Sass开发中非常非常重要,因为使用这些可以极大地提高我们的开发效率,所以这一章小伙伴们要重点学习。接下来我们一一给大家详细介绍。
Sass继承实例讲解
CSS具有2大特性:继承性和层叠性。CSS的继承性,指的是子元素继承了父元素的某些样式属性,例如在父元素中定义字体颜色(color),子元素会继承父元素的字体颜色。
在Sass中,我们可以使用“@extend”来继承一个样式块,从而实现代码的重用。
举例1:
.spriteAll { bakckground:url(images/sprite.png) no-repeat; } .sprite-1 { @extend .spriteAll; background-position:0 -30px; } .sprite-2 { @extend .spriteAll; background-position:0 -60px; }
编译出来的CSS代码如下:
.spriteAll, .sprite-1, .sprite-2 { bakckground: url(images/sprite.png) no-repeat; } .sprite-1 { background-position: 0 -30px; } .sprite-2 { background-position: 0 -60px; }
分析:
在这个例子中,我们定义了一个“.spriteAll”类用来存放公共样式,然后在“.sprite-1”和“.sprite-2”中使用@extend来继承“.spriteAll”类。
举例:
.btn { padding:6px 10px; border:1px solid silver; font-size:14px; } .btn-primary { @extend .btn; color:white; background-color:red; } .btn-second { @extend .btn; color:orange; background-color:green; }
编译出来的CSS代码如下:
.btn, .btn-primary, .btn-second { padding: 6px 10px; border: 1px solid silver; font-size: 14px; } .btn-primary { color: white; background-color: red; } .btn-second { color: orange; background-color: green; }
分析:
在这个例子中,我们定义了一个“.btn”类用来存放公共样式,然后在“.btn-primary”和“.btn-second”中使用@extend来继承“.btn”类。
从上面两个例子我们可以看出,继承这种方式来实现代码的重用是非常实用的。它使得代码更为精简,并且一目了然,具有更高的可读性和可维护性。
Sass占位符实例讲解
在Sass中,我们引入了占位符“%placeholder”来进一步优化“@extend”。我们先来看一个例子。
举例:使用继承“@extend”
.btn { padding:6px 10px; border:1px solid silver; font-size:14px; } .btn-primary { @extend .btn; color:white; background-color:red; } .btn-second { @extend .btn; color:orange; background-color:green; }
编译出来的CSS代码如下:
.btn, .btn-primary, .btn-second { padding: 6px 10px; border: 1px solid silver; font-size: 14px; } .btn-primary { color: white; background-color: red; } .btn-second { color: orange; background-color: green; }
分析:
从这个例子我们可以看出,继承“@extend”是非常好用的。通过@extend,我们可以直接在“.btn-primary”和“.btn-second”中插入定义好的“.btn”,这样每次只要你修改了“.btn”中的样式,“.btn-primary”和“.btn-second”中的样式都会同时修改。
但是稍微细心的小伙伴应该也发现了,如果我们的HTML中没有任何一个元素使用“.btn”的话,“.btn”存在的唯一目的就是仅仅用来给“.btn-primary”和“.btn-second”继承。也就是说,“.btn”这个类在编译出来的CSS中是多余的。那有没有更好的办法来实现我们预期效果呢?
在新版本的Sass中,引入了“占位符%placeholder”来优化“继承@extend”的输出。
举例:
%btn { padding:6px 10px; border:1px solid silver; font-size:14px; } .btn-primary { @extend %btn; color:white; background-color:red; } .btn-second { @extend %btn; color:orange; background-color:green; }
编译出来的CSS代码如下:
.btn-primary, .btn-second { padding: 6px 10px; border: 1px solid silver; font-size: 14px; } .btn-primary { color: white; background-color: red; } .btn-second { color: orange; background-color: green; }
分析:
上一个例子,我们是定义一个基类“.btn”(类,都是以“.”开头)。而在这个例子中,我们是定义一个占位符“%btn”(占位符,都是以“%”开头)。我们对比一下这两个例子的输出结果就可以知道,使用占位符的输出结果是不包含基类的。
“占位符%placeholder”并非用来替换“继承@extend”的,而是用来配合“继承@extend”来使用的。从上面我们可以知道,继承@extend有2种输出方式:
- (1)需要保留基类的:只使用@extend来实现;
- (2)不需要保留基类的:使用@extend配合%placeholder来实现;
此外在实际开发中,继承中的基类是否就一定要去掉呢?这个倒不一定。如果你的HTML结构需要用到基类,则不需要使用占位符的方式来去掉;如果你的HTML不需要用到基类,则建议使用占位符配合继承来去掉。
Sass混合宏实例介绍
在Sass中,我们可以使用“混合宏(mixin)”来处理经常被多个地方使用的相同的CSS代码块。混合宏,跟JavaScript中的函数很相似,我们可以称之为“Sass中的函数”。
一、混合宏的定义和调用
在Sass中,我们使用“@mixin”来定义一个混合宏,然后使用“@include”来调用一个混合宏。
语法:
//定义一个混合宏 @mixin 混合宏名 { 样式属性1:取值1; 样式属性2:取值2; …… } //调用一个混合宏 选择器 { @include 混合宏名; }
说明:
Sass中的混合宏跟C语言的宏是非常相似的。所谓的“宏”,指的是可重用的代码块。
@mixin用来定义一个混合宏,@include用来调用一个混合宏。此外,@mixin跟CSS3中的@font-face和@media语法是一样的。
举例:
@mixin radius { border-radius:5px; -webkit-border-radius:5px; -moz-border-radius:5px; } #header { color:red; @include radius; } #footer { color:green; @include radius; }
编译出来的CSS代码如下:
#header { color: red; border-radius: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px; } #footer { color: green; border-radius: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px; }
二、混合宏的参数
在Sass中,我们不仅可以定义“不带参数的混合宏”,也可以定义“带参数的混合宏”。其中,混合宏的参数可以是1个,也可以是N个。
举例:带一个参数的混合宏
@mixin radius($radius) { border-radius:$radius; -webkit-border-radius:$radius; -moz-border-radius:$radius; } #header { color:red; @include radius(3px); } #footer { color:green; @include radius(5px); }
编译出来的CSS代码如下:
#header { color: red; border-radius: 3px; -webkit-border-radius: 3px; -moz-border-radius: 3px; } #footer { color: green; border-radius: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px; }
举例:带多个参数的混合宏
@mixin center($width,$height) { width: $width; height: $height; position: absolute; top: 50%; left: 50%; margin-top: -($height) / 2; margin-left: -($width) / 2; } div { @include center(100px,80px); }
编译出来的CSS代码如下:
div { width: 100px; height: 80px; position: absolute; top: 50%; left: 50%; margin-top: -40px; margin-left: -50px; }
分析:
这个混合宏里面的CSS代码是一个功能代码块,是用来同时实现元素的水平居中和垂直居中的。在实际开发中,对于这些功能代码块,我们都是配合混合宏(mixin)来使用,非常的简单快速。现在大家体会到Sass比纯CSS强大的地方了吧。
在Sass中,我们还可以为混合宏传递的参数定义默认值。混合宏参数的默认值,跟变量的默认值是非常相似的,小伙伴们记得对比一下,这样更能加深理解和记忆。
举例:参数带默认值
@mixin radius($radius:3px) { border-radius:$radius; -webkit-border-radius:$radius; -moz-border-radius:$radius; } #header { color:red; @include radius; } #footer { color:green; @include radius(5px); }
编译出来的CSS代码如下:
#header { color: red; border-radius: 3px; -webkit-border-radius: 3px; -moz-border-radius: 3px; } #footer { color: green; border-radius: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px; }
分析:
在这个例子中,我们给“混合宏radius”传了一个参数“$radius”,并且给这个参数定义了一个默认值“3px”。如果我们页面有很多地方的圆角都是“3px”的话,那么这种默认值的方式就会非常
sass流程控制
Sass流程控制@if语句
在Sass中,我们可以使用“@if语句”来进行条件选择判断。Sass的条件选择语句共有3种:
- (1)@if…(单向选择);
- (2)@if…@else…(双向选择);
- (3)@if…@else if…(多向选择);
接下来,我们一一详细介绍这3种条件选择语句。
一、@if语句
在Sass中,我们可以使用“@if…”来实现单向选择。
举例:
div { @if (10px>5px) { border:1px solid gray; } }
编译出来的CSS代码如下:
div { border:1px solid gray; }
二、@if…@else…
在Sass中,我们可以使用“@if…@else…”来实现双向选择。
举例:
@mixin checkBlock($boolean:true) { @if $boolean { display:block; } @else { ; } } .block { @include checkBlock; } .hidden { @include checkBlock(false); }
编译出来的CSS代码如下:
.block { display: block; } .hidden { display: none; }
分析:
这里定义了带有一个参数的混合宏checkBlock,参数默认值为true。然后使用“@if…@else…”语句对传过来的参数进行判断,从而决定元素display属性值为block(显示),还是none(隐藏)。
三、@if…@else if…
在Sass中,我们可以使用“@if…@else if…”来实现多向选择。
举例:
@mixin checkColor ($width) { @if ($width>100px) { color:red; } @else if ($width<100px) { color:green; } @else { color:blue; } } div { @include checkColor(100px); }
编译出来的CSS代码如下:
div { color:blue; }
分析:
“@if…@else if…”这种多向选择的语句在Sass用得比较少,我们只需要简单了解一下即可。
@for循环
接触过Boostrap的小伙伴,估计都见过.col1~.col12这样的样式。在CSS中,对于这种样式我们一般都需要一个一个地书写。但是在Sass中,我们可以使用@for循环来实现。
在Sass中,我们可以使用“@for”来实现循环操作。其中,Sass中的@for循环有2种方式。
语法:
方式1:@for $i from 开始值 through 结束值 方式2:@for $i from 开始值 to 结束值
说明:
这2种方式是相似的,唯一的区别是:方式1包括结束值,方式2不包括结束值。其中“开始值”和“结束值”都是正整数。
举例1:
@for $i from 1 through 3 { .item-#{$i} { width:(20px * $i); } }
编译出来的CSS代码如下:
.item-1 { width:20px; } .item-2 { width:40px; } .item-3 { width:60px; }
分析:
如果将“@for $i from 1 through 3”改为“@for $i from 1 to 3”,则编译出来的CSS代码如下:
.item-1 { width:20px; } .item-2 { width:40px; }
举例2:
@for $i from 1 through 3 { .border-#{$i} { border:#{$i}px solid red; } }
编译出来的CSS代码如下:
.border-1 { border: 1px solid red; } .border-2 { border: 2px solid red; } .border-3 { border: 3px solid red; }
分析:
如果小伙伴们忘了“插值#{}”的用法,记得回去翻翻“ Sass插值 ”这一节。
Sass流程控制@while循环
在Sass中,我们也可以使用@while语句来实现循环操作。跟JavaScript一样,@while语句既是循环语句,也是条件判断语句。
语法:
@while(判断条件) { 执行语句; }
说明:
在Sass中,没有类似于JavaScript的“do...while...”这种语句。这一点小伙伴们要注意一下。
举例1:使用@while循环
$i:3; @while ($i>0) { .item-#{$i} { width: (20px + $i); } $i : ($i - 1); //递减操作 }
编译出来的CSS代码如下:
.item-3 { width: 23px; } .item-2 { width: 22px; } .item-1 { width: 21px; }
分析:
当然,对于上面这个例子,我们也可以使用for循环来实现,效果是一样的。
举例2:使用@for循环
@for $i from 1 through 3 { .item-#{$i} { width:(20px+$i); } }
编译出来的CSS代码如下:
.item-1 { width: 21px; } .item-2 { width: 22px; } .item-3 { width: 23px; }
分析:
细心的小伙伴们可能就会有疑问了:对于“width:(20px+$i);”这个,$i是一个数字,而20px是像素,这可以进行相加吗?其实,在之前“ Sass数据类型 ”这一节已经说过了:在Sass中,带有单位的数值我们也可以把它当做一个“数字”来处理。
此外,我们还要记得一点:带单位的数字与不带单位的数字是可以进行相加,结果是一个带单位的数字。但是带单位的数字与不带单位的数字是不可以相减的,小伙伴们可以自行测试一下。
Sass流程控制@each循环
除了@for以及@while这2种循环方式之外,Sass还为我们提供了另外一种循环方式:each循环。Sass中的each循环跟jQuery中的each循环很相似,大家对比一下。
语法:
@each $var in 列表值 { …… }
说明:
$var是一个变量,也可以根据后面列表值表示的内容需要写成$item、$color等。列表值,是Sass中的一种数据类型,可以称之为“Sass中的数组”。对于列表值,我们在之前的“ Sass数据类型 ”这一节已经接触过了。
举例:图片循环
$list:logo,banner,btn; @each $var in $list { .#{$var}-img { background-image:url("images/#{$var}.png"); } }
编译出来的CSS代码如下:
.logo { background-image: url("images/logo.png"); } .banner { background-image: url("images/banner.png"); } .btn { background-image: url("images/btn.png"); }
分析:
在这个例子中,我们使用@each循环快速生成背景图片样式。这种技巧在实际开发中也经常被用到。
举例:图片合并
$list:sprite1,sprite2,sprite3; %spriteAll { background:url("images/sprite.png") no-repeat; } @each $var in $list { .#{$var} { @extend %spriteAll; background-position: 0 index($list,$var) * (-30px); } }
编译出来的CSS代码如下:
.sprite1, .sprite2, .sprite3 { background: url("images/sprite.png") no-repeat; } .sprite1 { background-position: 0 -30px; } .sprite2 { background-position: 0 -60px; } .sprite3 { background-position: 0 -90px; }
分析:
从上面这个例子可以看出,我们使用@each循环来操作CSS Sprite图片是非常方便的。CSS Sprite技巧在实际开发中大量用到,具体原理以及使用请参考 《css sprite讲解与使用实例》
举例:
$properties:(margin,padding); @mixin setValue($side , $value) { @each $prop in $properties { #{$prop}-#{$side}:$value; } } .login-box { @include setValue(top , 14px); }
编译出来的CSS代码如下:
.login-box { margin-top: 14px; padding-top: 14px; }