sass入门

编译

使用 sass --watch监控文件的改变,并对其进行实时编译
语法

  • sass --watch input.sass:output.css // 表示监控input.sass的改变,并实时编译,输出为output.css
  • sass --watch input-dir:output-dir // 监控input-dir文件夹下的所有sass或scss文件的改变,并实时编译到output-dir文件夹下

gulp的自动化编译脚本

需要安装gulp和gulp-sass

  var gulp = require('gulp');
  var sass = require('gulp-sass');
  
  gulp.task = ('sass', function(){
    gulp.src('./scss/*.scss')
        .pipe(sass({outputStyle: 'expressed'}).on('error', sass.logError))
        .pipe(gulp.dest('./css'));
  });
  
  gulp.task('watch', function(){
    gulp.watch('scss/*.scss', ['sass']);
  });
  
  gulp.task('build-sass', ['sass', 'watch']);

.map文件

编译后生成的.map文件便于我们在浏览器中直接调试sass文件

常见的编译错误

除去编写sass的语法错误外,常见的编码错误有:

  • 字符编码错误
    在sass文件中将字符编码设置为: @charset "utf-8"
  • 中文路径导致的错误
    路径不要出现中文

编译后文件的输出风格

  • 嵌套输出方式:nested
    在编译时带上参数:--style nested
    这种风格的大括号不占用一行
  • 展开输出方式:expanded
    在编译时带上参数:--style expanded
    这种风格,大括号会另起一行
  • 紧凑输出方式:compact
    带上参数:--style compact
    这种风格:单行css的形式
  • 压缩输出方式:compressed
    带上参数:--style compressed
    这种风格:所有css在一行

语法

声明变量

sass的变量包含三个部分:

  • 声明变量的符号 "$"
  • 变量名称
  • 赋予变量的值
    如:
// 变量名为:width,值为:300px
$width: 300px; 

// 如果值后面加上 `!default` 表示默认值
$fontSize: 14px !default;

两种形式变量:

  • 普通变量: 如:$width: 300px

  • 默认变量:如:$fontSize: 14px !default
    如果要覆盖默认变量,只需要在它的前面重新声明即可

    $baseLineHeight: 2;
    $baseLineHeight: 1.5 !default;
    body{
        line-height: $baseLineHeight; 
    }
    

sass的变量有作用域
根据作用域的不同,分为:全局变量局部变量

  • 全局变量:定义在元素外部
  • 局部变量: 定义在局部范围的变量,当局部变量与全局变量同名时,局部变量会覆盖全局变量

什么时候声明变量?
三个原则:

  • 该值至少重复出现两次以上
  • 该值至少可能会被更新一次
  • 该值所有的表现都与变量有关(非巧合)

一个sass的在线编译器

嵌套-选择器嵌套

三种嵌套方式:

  • 选择器嵌套
    如:

    nav {
      a {
        color: red;
        header & {
          color:green;
        }
      }  
    }
    转换为 css
    nav a {
      color: red;
    }
    header nav a {
      color: green;
    }
    
  • 属性嵌套
    有很多属性是有相同的前缀的,如:margin、padding、font等属性,可以像下面这样简写:

    .box {
      border: {
       top: 1px solid red;
       bottom: 1px solid green;
      }
    }
    // 转换为css
    .box {
      font-size: 12px;
      font-weight: bold;
    }
    
  • 伪类嵌套
    与属性嵌套非常类似,只不过需要借助"&"符号一起配合使用,如:

    .box{
      &:before {
        content:"伪元素嵌套";
      }
    }
    // 转换为css
    .box:before{
      content: "伪元素嵌套";
    }
    

混合宏

声明宏

  • 不带参数混合宏
    在sass中,使用"@mixin"来声明一个混合宏
    如:
@mixin border-radius{
  -webkit-border-radius: 5px;
  border-radius: 5px;
}

@mixin是用来申明混合宏的关键字,
border-radius是混合红的名称,
大括号里面是复用的样式代码

  • 带参数混合宏
    在声明宏时带参数
@mixin border-radius($radius: 5px){
  -webkit-border-radius: $radius;
  border-radius: $radius;
}
  • 复杂的混合宏
    可以在大括号里面带有逻辑关系
    如:
  @if length($shadow) >= 1{
    @include prefixer(box-shadow, $shadow);
  } @else {
    $shadow: 0 0 4px rgba(0, 0, 0, .30;
    @include prefixer(box-shadow, $shadow);
}

注意:$shadown...中的...表示带有多个参数,当带有多个参数时,可以使用...来代替,
@include:表示调用混合宏

调用混合宏

sass中使用@mixin声明混合宏,使用@include调用混合宏
如:

// 声明一个border-radius 的混合宏
@mixin border-radius($radius: 5px){
  -webkit-border-radius: $radius;
  border-radius: $radius;
}

// 调用混合宏
button {
   @include border-radius;
}

编译出来的css:

button {
  -webkit-border-radius: 3px;
  border-radius: 3px;
}

混合宏的不足

最大的不足是:生成冗余的代码块
如:

@mixin border-radius{
  -webkit-border-radius: 3px;
  border-radius: 3px;
}

.box {
  @include border-radius;
  margin-bottom: 5px;
}

.btn {
  @include border-radius;
}

编译后的css:

.box {
  -webkit-border-radius: 3px;
  border-radius: 3px;
  margin-bottom: 5px;
}

.btn {
  -webkit-border-radius: 3px;
  border-radius: 3px;
}

.box.btn都调用了相同的内容,但是sass并未将其合并在一起,这便是混合宏最大的不足

扩展/继承

sass中的继承跟js中的继承类似,只不过它们继承的是样式,
sass中的继承通过@extend, 如下代码:

// scss 
.btn{
  border: 1px solid #ccc;
  padding: 6px 10px;
  font-size: 14px;
}

.btn-primary{
  background-color: #f36;
  color: #fff;
  @extend .btn;   //继承.btn
}

.btn-second {
  background-color: orange;
  color: #fff;
  @extend .btn;
}

编译出来之后的css:

//CSS
.btn, .btn-primary, .btn-second {
  border: 1px solid #ccc;
  padding: 6px 10px;
  font-size: 14px;
}

.btn-primary {
  background-color: #f36;
  color: #fff;
}

.btn-second {
  background-clor: orange;
  color: #fff;
}

通过继承便可以实现代码的复用,可以解决混合宏生成重复代码的问题

占位符 %placeholder

sass中的占位符功能很强大、很实用
使用占位符声明的代码块,如果没有被@extend调用,就不会生成CSS代码,
可以取代以前CSS中的基类造成的代码冗余的情况。
如:

%mt5 {
  margin-top: 5px;
}

%pt5 {
  padding-top: 5px;
}

上面这段代码没有被@extend引用,因此在编译时,不会生成冗余的CSS代码
如:

//SCSS
%mt5 {
  margin-top: 5px;
}
%pt5{
  padding-top: 5px;
}

.btn {
  @extend %mt5;
  @extend %pt5;
}

.block {
  @extend %mt5;

  span {
    @extend %pt5;
  }
}

编译出来的CSS

//CSS
.btn, .block {
  margin-top: 5px;
}

.btn, .block span {
  padding-top: 5px;
}

从编译出来的CSS代码可以看出,通过@extend调用的占位符,
编译出来的代码会将相同的代码合并在一起,这就是我们需要的

混合宏 VS 继承 VS 占位符

关于什么时候该用哪种方式,往往很纠结,以下分析:

  • 混合宏的使用
//SCSS中混合宏使用
@mixin mt($var){
  margin-top: $var;  
}

.block {
  @include mt(5px);

  span {
    display:block;
    @include mt(5px);
  }
}

.header {
  color: orange;
  @include mt(5px);

  span{
    display:block;
    @include mt(5px);
  }
}

编译出来:

.block {
  margin-top: 5px;
}
.block span {
  display: block;
  margin-top: 5px;
}

.header {
  color: orange;
  margin-top: 5px;
}
.header span {
  display: block;
  margin-top: 5px;
}

结论: 从编译出来的css可以知道,使用混合宏时并不会合并相同的样式代码,造成代码的冗余,
但是它可以传递参数

建议:如果代码中涉及到变量,建议使用混合宏来创建相同的代码块。

  • sass中的继承
    先上代码:
//SCSS 继承的运用
.mt{
  margin-top: 5px;  
}

.block {
  @extend .mt;

  span {
    display:block;
    @extend .mt;
  }
}

.header {
  color: orange;
  @extend .mt;

  span{
    display:block;
    @extend .mt;
  }
}

编译出来的css:


.mt, .block, .block span, .header, .header span {
  margin-top: 5px;
}

.block span {
  display: block;
}

.header {
  color: orange;
}
.header span {
  display: block;
}

总结: 使用继承后,编译出来的CSS会将使用继承的代码块合并在一起
通过组合选择器的方式展现, 相对于混合宏而言,要干净的多,但是,
继承不能传递参数

建议:如果代码块中不需要传递任何变量参数,而且有一个基类已在文件中存在,
那么建议使用sass的继承。

  • 占位符
    代码如下:
//SCSS中占位符的使用
%mt{
  margin-top: 5px;  
}

.block {
  @extend %mt;

  span {
    display:block;
    @extend %mt;
  }
}

.header {
  color: orange;
  @extend %mt;

  span{
    display:block;
    @extend %mt;
  }
}

编译后的代码:

.block, .block span, .header, .header span {
  margin-top: 5px;
}

.block span {
  display: block;
}

.header {
  color: orange;
}
.header span {
  display: block;
}

总结:编译出来的css代码与使用继承的基本相同,只是不会在
代码中生成占位符mt的选择器,占位符和继承的主要区别:占位符是
独立定义,不调用的时候是不会在CSS中产生任何代码;继承是首先有
一个基类存在,不管调用与不调用,基类的样式都将会出现在编译后的的CSS代码中

插值#{}

如下代码:

$properties: (margin, padding);
@mixin set-value($side, $value) {
    @each $prop in $properties {
        #{$prop}-#{$side}: $value;
    }
}
.login-box {
    @include set-value(top, 14px);
}

编译出来:

.login-box {
    margin-top: 14px;
    padding-top: 14px;
}

数据类型

字符串

  • 有引号字符串
  • 无引号字符串
    在编译CSS文件时不会改变其类型。只有一种例外:
    使用#{}插值语句时,有引号字符串将被编译为无引号字符串
    如:
@mixin firefox-message($selector) {
  body.firefox #{$selector}:before {
    content: "Hi, Firefox users!";
  }
}
@include firefox-message(".header");

编译为:

body.firefox .header:before {
  content: "Hi, Firefox users!"; }

值列表

值列表就是:使用空格逗号分隔的一些列的值
如:

margin: 10px 15px 0 0 
//或
font-size: Helvetica, Arial, sans-serif

Sass列表函数赋予了值列表更多功能:
如:

  • nth函数:可以直接访问值列表中的某一项
  • join函数:可以将多个值列表串在一起
  • append函数:可以在值列表中添加值
  • @each函数:可以遍历值列表

运算

加法和减法运算

注意:在进行加减法运算时,如果单位不同,会出现报错

.box {
  width: 20px + 10px;
}

乘法运算

注意:乘法与加减法略有不同,当两个值的单位相同时,只需要写上一个单位,否则会报错
如:

.box {
  width: 10 * 2px;     // 只需要写一个单位即可
}

如果改为如下所示,会报错:

.box {
  width: 10px * 2px;  // 两个值都加上单位,会报错
}

除法运算

因为除法运算符 “/” 在CSS中有特殊含义,如设置字体时添加行高,
因此,如果出现以下几种情况,“/” 会被当做除法,如:

  • 如果数值或它的任意部分是存储在一个变量中或是函数的返回值
  • 如果数值被圆括号包围(如果需要进行除法运算,直接使用圆括号包围最为保险)
  • 如果数值是另一个数学表达式的一部分
    示例如下:
//scss
p {
  font: 10px/8px/         // 纯CSS, 不是除法运算
  $width: 1000px;
  width: $width / 2;      // 使用了变量,是除法运算
  width: round(1.5)/2;    // 使用了函数,是除法运算
  height: (500px / 2);    // 使用了圆括号,是除法运算
  margin-left: 5px + 8px/2px;   // 使用了加(+)号,是除法运算
}

注意:当两个带有相同单位的数值进行除法运算时,最终会被编译为没有单位的css

.box {
  width: (1000px / 100px);
}

编译出来的css:

.box {
  width: 10;
}

颜色运算

sass中对颜色进行算术运算是分段运算的,也就是说,红、绿和蓝各个颜色分段单独进行运算
如:

p {
  color: #010203 * 2;
}

字符运算

sass中通过加法符号 “ + ” 对字符串进行连接
如:

$content: 'hello' + '' + 'Sass!';
.box:before{
  content: '#{$content}';
}

你可能感兴趣的:(sass入门)