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}';
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345

推荐阅读更多精彩内容

  • 声明变量 定义变量的语法: 在有些编程语言中(如,JavaScript)声明变量都是使用关键词“var”开头,但是...
    Junting阅读 1,464评论 0 6
  • 2015年10月20日 1.嵌套 Sass 中还提供了选择器嵌套功能,但这也并不意味着你在 Sass 中的嵌套是无...
    a0d560da7818阅读 604评论 0 1
  • 很详细的sass入门指南,学习一下。原文sass入门指南css预处理器已经算不上一个新鲜的词了,当前比较有代表性的...
    hzrWeber阅读 1,014评论 0 18
  • 一,CSS 预处理器 CSS 预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为 CSS 增加了一...
    冯傻大粗阅读 440评论 0 0
  • 喂,你是不是读书读傻了!也许吧! 舅舅在电话里说,这么多年了你怎么还在读书,啥时候毕业,我苦笑着说就快了,就快要走...
    不识故阅读 333评论 2 0