不管是 Sass 的语法格式还是 SCSS 的语法格式,他们的功能都是一样的。
特别提醒:“.sass”只能使用 Sass 老语法规则(缩进规则),“.scss”使用的是 Sass 的新语法规则,也就是 SCSS 语法规则(类似 CSS 语法格式)。
Sass 的编译有多种方法:
命令编译是指使用你电脑中的命令终端,通过输入 Sass 指令来编译 Sass。这种编译方式是最直接也是最简单的一种方式。因为只需要在命令终端输入:
单文件编译:
sass <要编译的Sass文件路径>/style.scss:<要输出CSS文件路径>/style.css
这是对一个单文件进行编译,如果想对整个项目所有 Sass 文件编译成 CSS 文件,可以这样操作:
多文件编译:
sass sass/:css/
上面的命令表示将项目中“sass”文件夹中所有“.scss”(“.sass”)文件编译成“.css”文件,并且将这些 CSS 文件都放在项目中“css”文件夹中。
缺点及解决方法:
在实际编译过程中,你会发现上面的命令,只能一次性编译。每次个性保存“.scss”文件之后,都得重新执行一次这样的命令。如此操作太麻烦,其实还有一种方法,就是在编译 Sass 时,开启“watch”功能,这样只要你的代码进行修改,都能自动监测到代码的变化,并且给你直接编译出来:
sass --watch <要编译的Sass文件路径>/style.scss:<要输出CSS文件路径>/style.css例如:sass --watch sass/bootstrap.scss:css/bootstrap.css
2.GUI编译
对于 GUI 界面编译工具,目前较为流行的主要有:
相比之下,推荐使用以下两个:
最为常见的一个错误就是字符编译引起的。在Sass的编译的过程中,是不是支持“GBK”编码的。所以在创建 Sass 文件时,就需要将文件编码设置为“utf-8”。
另外一个错误就是路径中的中文字符引起的。建议在项目中文件命名或者文件目录命名不要使用中文字符。而至于人为失误造成的编译失败,在编译过程中都会有具体的说明,大家可以根据编译器提供的错误信息进行对应的修改。
三、Sass样式输出方式
在编译的时候带上参数“ --style nested”:
sass --watch test.scss:test.css --style nested
2.嵌套输出方式 expanded
sass --watch test.scss:test.css --style expanded
这个输出的 CSS 样式风格和 nested 类似,只是大括号在另起一行
3.紧凑输出方式 compact
在编译的时候带上参数“ --style compact”:
sass --watch test.scss:test.css --style compact
4.压缩输出方式 compressed
在编译的时候带上参数“ --style compressed”:
sass --watch test.scss:test.css --style compressed
压缩输出方式会去掉标准的 Sass 和 CSS 注释及空格。
四、Sass基础
Sass 的变量包括三个部分:
普通变量定义之后可以在全局范围内使用。
sass 的默认变量仅需要在值后面加上 !default 即可。
$baseLineHeight:1.5 !default;
body{
line-height: $baseLineHeight;
}
编译后的css代码:
body{ line-height:1.5; }
sass 的默认变量一般是用来设置默认值,然后根据需求来覆盖的,覆盖的方式也很简单,只需要在默认变量之前重新声明下变量即可。
$baseLineHeight: 2;
$baseLineHeight: 1.5 !default;
body{
line-height: $baseLineHeight;
}
编译后的css代码:
body{
line-height:2;
}
默认变量的价值在进行组件化开发的时候会非常有用。
3.局部变量和全局变量
css 的结果:代码例子:
//SCSS $color: orange !default;//定义全局变量(在选择器、函数、混合宏...的外面定义的变量为全局变量) .block { color: $color;//调用全局变量 } em { $color: red;//定义局部变量 a { color: $color;//调用局部变量 } } span { color: $color;//调用全局变量 }
.block { color: orange; } em a { color: red; } span { color: orange; }
上面的示例可以得知,在元素内部定义的变量不会影响其他元素。如此可以简单的理解成,全局变量就是定义在元素外面的变量,如下代码:
$color:orange !default;$color 就是一个全局变量
而定义在元素内部的变量,比如 $color:red; 是一个局部变量。除此之外,Sass 现在还提供一个 !global 参数。
当在局部范围(选择器内、函数内、混合宏内...)声明一个已经存在于全局范围内的变量时,局部变量就成为了全局变量的影子。基本上,局部变量只会在局部范围内覆盖全局变量。
上面例子中的 em 选择器内的变量 $color 就是一个全局变量的影子。
什么时候声明变量?
创建变量只适用于感觉确有必要的情况下。不要为了某些骇客行为而声明新变量,这丝毫没有作用。只有满足所有下述标准时方可创建新变量:
1. 该值至少重复出现了两次;2. 该值至少可能会被更新一次;3. 该值所有的表现都与变量有关(非巧合)。基本上,没有理由声明一个永远不需要更新或者只在单一地方使用变量。
4.嵌套
选择器嵌套为样式表的作者提供了一个通过局部选择器相互嵌套实现全局选择的方法,Sass 的嵌套分为三种:
避免选择器嵌套:
为了防止此类情况,我们应该尽可能避免选择器嵌套。
5.混合宏
1、声明混合宏
不带参数混合宏:
在 Sass 中,使用“@mixin”来声明一个混合宏。如:
@mixinborder-radius{
-webkit-border-radius: 5px;
border-radius: 5px;
}
其中 @mixin 是用来声明混合宏的关键词,有点类似 CSS 中的 @media、@font-face 一样。border-radius 是混合宏的名称。大括号里面是复用的样式代码。
带参数混合宏:
除了声明一个不带参数的混合宏之外,还可以在定义混合宏时带有参数,如:
@mixin border-radius($radius:5px){
-webkit-border-radius: $radius;
border-radius: $radius;
}
2、调用混合宏
在实际调用中,其匹配了一个关键词“@include”来调用声明好的混合宏。例如在定义了一个圆角的混合宏“border-radius”:
@mixin border-radius{
-webkit-border-radius: 3px;
border-radius: 3px;
}
在一个按钮中要调用定义好的混合宏“border-radius”,可以这样使用:
button {@include border-radius;}
这个时候编译出来的 CSS:
button {
-webkit-border-radius: 3px;
border-radius: 3px;
}
3、传参
Sass 的混合宏有一个强大的功能,可以传参,那么在 Sass 中传参主要有以下几种情形:
A) 传一个不带值的参数
在混合宏中,可以传一个不带任何值的参数,比如:
@mixin border-radius($radius){ -webkit-border-radius: $radius; border-radius: $radius; }
在混合宏“border-radius”中定义了一个不带任何值的参数“$radius”,在调用的时候可以给这个混合宏传一个参数值:
.box { @include border-radius(3px); }
这里表示给混合宏传递了一个“border-radius”的值为“3px”。编译出来的 CSS:
在 Sass 的混合宏中,还可以给混合宏的参数传一个默认值,例如:.box { -webkit-border-radius: 3px; border-radius: 3px; }B) 传一个带值的参数
@mixin border-radius($radius:3px){ -webkit-border-radius: $radius; border-radius: $radius; }
在混合宏“border-radius”传了一个参数“$radius”,而且给这个参数赋予了一个默认值“3px”。
在调用类似这样的混合宏时,会多有一个机会,假设你的页面中的圆角很多地方都是“3px”的圆角,那么这个时候只需要调用默认的混合宏“border-radius”:
但有的时候,页面中有些元素的圆角值不一样,那么可以随机给混合宏传值,如:.btn { @include border-radius; }
编译出来的 CSS:
.btn { -webkit-border-radius: 3px; border-radius: 3px; }
编译出来的 CSS:.box { @include border-radius(50%); }
Sass 混合宏除了能传一个参数之外,还可以传多个参数,如:.box { -webkit-border-radius: 50%; border-radius: 50%; }B) 传多个参数
在混合宏“center”就传了多个参数。在实际调用和其调用其他混合宏是一样的:@mixin center($width,$height){ width: $width; height: $height; position: absolute; top: 50%; left: 50%; margin-top: -($height) / 2; margin-left: -($width) / 2; }
有一个特别的参数 “…” 。当混合宏传的参数过多之时,可以使用参数来替代,如:.box-center { @include center(500px,300px); }
编译出来 CSS:
.box-center { width: 500px; height: 300px; position: absolute; top: 50%; left: 50%; margin-top: -150px; margin-left: -250px; }
在实际调用中:@mixin box-shadow($shadows...){ @if length($shadows) >= 1 { -webkit-box-shadow: $shadows; box-shadow: $shadows; } @else { $shadows: 0 0 2px rgba(#000,.25); -webkit-box-shadow: $shadow; box-shadow: $shadow; } }
编译出来的CSS:.box { @include box-shadow(0 0 1px rgba(#000,.5),0 0 2px rgba(#000,.2)); }
在 Sass 中通过关键词 “ @extend ” 来继承已存在的类样式块,从而实现代码的继承。.box { -webkit-box-shadow: 0 0 1px rgba(0, 0, 0, 0.5), 0 0 2px rgba(0, 0, 0, 0.2); box-shadow: 0 0 1px rgba(0, 0, 0, 0.5), 0 0 2px rgba(0, 0, 0, 0.2); }6.扩展和继承
7.占位符
%mt5 { margin-top: 5px; } %pt5{ padding-top: 5px; }这段代码没有被 @extend 调用,他并没有产生任何代码块。只有通过 @extend 调用才会产生代码:
//SCSS %mt5 { margin-top: 5px; } %pt5{ padding-top: 5px; } .btn { @extend %mt5;@extend %pt5; } .block { @extend %mt5; span { @extend %pt5; } }//CSS .btn, .block { margin-top: 5px; } .btn, .block span { padding-top: 5px; }从编译出来的 CSS 代码可以看出,通过 @extend 调用的占位符,编译出来的代码会将相同的代码合并在一起。
8.混合宏 VS 继承 VS占位符
a) Sass 中的混合宏使用
总结:编译出来的 CSS 清晰告诉了大家,他不会自动合并相同的样式代码,如果在样式文件中调用同一个混合宏,会产生多个对应的样式代码,造成代码的冗余,这也是 CSSer 无法忍受的一件事情。不过他并不是一无事处,他可以传参数。
个人建议:如果你的代码块中涉及到变量,建议使用混合宏来创建相同的代码块。
b) Sass 中继承
总结:使用继承后,编译出来的 CSS 会将使用继承的代码块合并到一起,通过组合选择器的方式向大家展现,比如 .mt, .block, .block span, .header, .header span。这样编译出来的代码相对于混合宏来说要干净的多,也是 CSSer 期望看到。但是他不能传变量参数。
个人建议:如果你的代码块不需要专任何变量参数,而且有一个基类已在文件中存在,那么建议使用 Sass 的继承。
c) 占位符
总结:编译出来的 CSS 代码和使用继承基本上是相同,只是不会在代码中生成占位符的选择器。那么占位符和继承的主要区别的,“占位符是独立定义,不调用的时候是不会在 CSS 中产生任何代码;继承是首先有一个基类存在,不管调用与不调用,基类的样式都将会出现在编译出来的 CSS 代码中。”
在 Sass 中注释有两种方式:
1、类似 CSS 的注释方式,使用 ”/* ”开头,结属使用 ”*/ ”
2、类似 JavaScript 的注释方式,使用“//”
两者区别,前者会在编译出来的 CSS 显示,后者在编译出来的 CSS 中不会显示
10.数值类型
在 Sass 中包含以下几种数据类型:
SassScript 也支持其他 CSS 属性值(property value),比如 Unicode 范围,或 !important 声明。然而,Sass 不会特殊对待这些属性值,一律视为无引号字符串。使用 #{ }插值语句时,有引号字符串将被编译为无引号字符串,这样方便了在混合指令 (mixin) 中引用选择器名
1.@if@if 指令可以根据条件来处理样式块,如果条件为 true 返回一个样式块,反之 false 返回另一个样式块。在 Sass 中除了 @if 之,还可以配合 @else if 和 @else 一起使用。
假设要控制一个元素隐藏或显示,就可以定义一个混合宏,通过 @if...@else... 来判断传进参数的值来控制 display 的值。
@mixin blockOrHidden($boolean:true) {@if$boolean { @debug "$boolean is #{$boolean}"; display: block; } @else { @debug "$boolean is #{$boolean}"; display: none; } } .block { @include blockOrHidden; } .hidden{ @include blockOrHidden(false); }
@for $i from <start> through <end> @for $i from <start> to <end>
- $i 表示变量
- start 表示起始值
- end 表示结束值
这两个的区别是关键字 through 表示包括 end 这个数,而 to 则不包括 end 这个数。
如下代码,先来个使用 through 关键字的例子:
@for $i from 1 through 3 {
.item-#{$i} { width: 2em * $i; }
}
再来个 to 关键字的例子:
@for $i from 1 to 3 { .item-#{$i} { width: 2em * $i; } }
@for应用在网格系统生成各个格子 class 的代码:
$grid-prefix: div !default; $grid-width: 60px !default; $grid-gutter: 20px !default; %grid { float: left; margin-left: $grid-gutter / 2; margin-right: $grid-gutter / 2; } @for $i from 1 through 12 { .#{$grid-prefix}#{$i}{ width: $grid-width * $i + $grid-gutter * ($i - 1); @extend %grid; } }3.@while@while 指令也需要 SassScript 表达式(像其他指令一样),并且会生成不同的样式块,直到表达式值为 false 时停止循环。这个和 @for 指令很相似,只要 @while 后面的条件为 true 就会执行。
用例:
$types: 4; $type-width: 20px; @while$types > 0 { .while-#{$types} { width: $type-width + $types; } $types: $types - 1; }4.@each
@each 循环就是去遍历一个列表,然后从列表中取出对应的值。@each 循环指令的形式:
@each $var in <list>在下面的例子中,$var 就是一个变量名,<list> 是一个 SassScript 表达式,他将返回一个列表值。变量 $var 会在列表中做遍历,并且遍历出与 $var 对应的样式块。
$list: adam john wynn mason kuroir;//$list 就是一个列表 @mixin author-images { @each $author in $list { .photo-#{$author} { background: url("/images/avatars/#{$author}.png") no-repeat; } } } .author-bio { @include author-images; }五、Sass函数功能
1.字符串函数
(1)、unquote()
unquote() 函数主要是用来删除一个字符串中的引号,如果这个字符串没有带有引号,将返回原始的字符串。
(2)、quote()
quote() 函数刚好与 unquote() 函数功能相反,主要 用来给字符串 添加引号 。如果字符串,自身带有引号会统一换成双引号 ""。使用 quote() 函数只能给字符串增加双引号,而且字符串 中间有 单引号或者空格,特殊符号 时 ,需要用单引号或双引号括起,否则编译的时候将会报错。(3)、To-upper-case()
To-upper-case() 函数将字符串小写字母转换成大写字母
(4)、To-lower-case()
To-lower-case() 函数将字符串大写字母转换成小写字母
2.数字函数
- percentage($value):将一个不带单位的数转换成百分比值;
- round($value):将数值四舍五入,转换成一个最接近的整数;
- ceil($value):将大于自己的小数转换成下一位整数;
- floor($value):将一个数去除他的小数部分;
- abs($value):返回一个数的绝对值;
- min($numbers…):找出几个数值之间的最小值;
- max($numbers…):找出几个数值之间的最大值;
- random(): 获取随机数
3.列表函数
- length($list):返回一个列表的长度值;
- nth($list, $n):返回一个列表中指定的某个标签值
- join($list1, $list2, [$separator]):只能将两个列给连接在一起,变成一个列表;
- append($list1, $val, [$separator]):将某个值放在列表的最后;
如果没有明确的指定 $separator 参数值,其默认值是 auto。
当然,在 append() 函数中,可以显示的设置 $separator 参数,
- zip($lists…):将几个列表结合成一个多维的列表;
zip(1px 2px 3px,solid dashed dotted,green blue red) >> ((1px "solid" #008000), (2px "dashed" #0000ff), (3px "dotted" #ff0000))
在使用zip()函数时,每个单一的列表个数值必须是相同的否则将会出错。
- index($list, $value):返回一个值在列表中的位置值。如果指定的值不在列表中(没有找到相应的值),那么返回的值将是 false
4.Introspection函数
- type-of($value):返回一个值的类型,
- unit($number):返回一个值的单位
- unitless($number):判断一个值是否带有单位
- comparable($number-1, $number-2):判断两个值是否可以做加、减和合并
当条件成立返回一种值,当条件不成立时返回另一种值:
if($condition,$if-true,$if-false)上面表达式的意思是当 $condition 条件成立时,返回的值为 $if-true,否则返回的是 $if-false 值。
>> if(true,1px,2px) 1px >> if(false,1px,2px) 2px5.Maps函数
Sass 的 map 常常被称为数据地图,也有人称其为数组,因为他总是以 key:value 成对的出现,但其更像是一个 JSON 数据。如:
$map: ( $key1: value1, $key2: value2, $key3: value3 )
- map-get($map,$key):根据给定的 key 值,返回 map 中相关的值。
- map-merge($map1,$map2):将两个 map 合并成一个新的 map。
- map-remove($map,$key):从 map 中删除一个 key,返回一个新 map。
- map-keys($map):返回 map 中所有的 key。
- map-values($map):返回 map 中所有的 value。
- map-has-key($map,$key):根据给定的 key 值判断 map 是否有对应的 value 值,如果有返回 true,否则返回 false。
- keywords($args):返回一个函数的参数,这个参数可以动态的设置 key 和 value。
6.RGB颜色函数
- rgb($red,$green,$blue):根据红、绿、蓝三个值创建一个颜色;
- rgba($red,$green,$blue,$alpha):根据红、绿、蓝和透明度值创建一个颜色;
- red($color):从一个颜色中获取其中红色值;
- green($color):从一个颜色中获取其中绿色值;
- blue($color):从一个颜色中获取其中蓝色值;
- mix($color-1,$color-2,[$weight]):把两种颜色根据一定比例(默认50%)混合在一起。
7.HSL函数
- hsl($hue,$saturation,$lightness):通过色相(hue)、饱和度(saturation)和亮度(lightness)的值创建一个颜色;
- hsla($hue,$saturation,$lightness,$alpha):通过色相(hue)、饱和度(saturation)、亮度(lightness)和透明(alpha)的值创建一个颜色;
- hue($color):从一个颜色中获取色相(hue)值;
- saturation($color):从一个颜色中获取饱和度(saturation)值;
- lightness($color):从一个颜色中获取亮度(lightness)值;
- adjust-hue($color,$degrees):通过改变一个颜色的色相值,创建一个新的颜色;
- lighten($color,$amount):通过改变颜色的亮度值,让颜色变亮,创建一个新的颜色;
- darken($color,$amount):通过改变颜色的亮度值,让颜色变暗,创建一个新的颜色;
- saturate($color,$amount):通过改变颜色的饱和度值,让颜色更饱和,从而创建一个新的颜色
- desaturate($color,$amount):通过改变颜色的饱和度值,让颜色更少的饱和,从而创建出一个新的颜色;
- grayscale($color):将一个颜色变成灰色,相当于desaturate($color,100%);
- complement($color):返回一个补充色,相当于adjust-hue($color,180deg);
- invert($color):反回一个反相色,红、绿、蓝色值倒过来,而透明度不变。
8.Opacity函数
- alpha($color) /opacity($color):获取颜色透明度值;
- rgba($color, $alpha):改变颜色的透明度值;
- opacify($color, $amount) / fade-in($color, $amount):使颜色更不透明;
- transparentize($color, $amount) / fade-out($color, $amount):使颜色更加透明。
六、Sass规则
@import 根据文件名引入。 默认情况下,它会寻找 Sass 文件并直接引入, 但是,在少数几种情况下,它会被编译成 CSS 的 @import 规则:
如果上述情况都没有出现,并且扩展名是 .scss 或 .sass, 该名称的 Sass 或 SCSS 文件就会被引入。 如果没有扩展名, Sass 将试着找出具有 .scss 或 .sass 扩展名的同名文件并将其引入。
2.@media
$media: screen; $feature: -webkit-min-device-pixel-ratio; $value: 1.5; @media #{$media} and ($feature: $value) { .sidebar { width: 500px; } }
编译出来的 CSS:
@media screen and (-webkit-min-device-pixel-ratio: 1.5) { .sidebar { width: 500px; } }3.@extend
Sass 中的 @extend 是用来扩展选择器或占位符。
.error {
border: 1px #f00;
background-color: #fdd;
}
.error.intrusion {
background-image: url("/image/hacked.png");
}
.seriousError {
@extend .error;
border-width: 3px;
}
被编译为:
.error, .seriousError {
border: 1px #f00;
background-color: #fdd; }
.error.intrusion, .seriousError.intrusion {
background-image: url("/image/hacked.png"); }
.seriousError {
border-width: 3px; }
4.@at-root
@at-root 从字面上解释就是跳出根元素。当你选择器嵌套多层之后,想让某个选择器跳出,此时就可以使用 @at-root。
.a {
color: red;
.b {
color: orange;
.c {
color: yellow;
@at-root .d {
color: green;
}
}
}
}
编译出来的CSS
.a {color: red;}
.a .b {color: orange;}
.a .b .c {color: yellow;}
.d {color: green;}
5.@debug
@debug 在 Sass 中是用来调试的,当你的在 Sass 的源码中使用了 @debug 指令之后,Sass 代码在编译出错时,在命令终端会输出你设置的提示 Bug:
@debug 10em + 12em;
会输出:Line 1 DEBUG: 22em
6.@warn,@error