SASS基础教程

本文简单的介绍SASS预处理语言,更多的应用请参考官方文档

一、什么是SASS

二、为什么使用SASS

三、安装SASS

四、初次尝试SASS

数据类型

SASS中有着如下数据类型:

  • 数字:1 2 3 10px
  • 字符串:"foo" 'far' baz (注意baz为“无引号字符串”)
  • 颜色:blue #04a3f9 rgba(255, 0, 0, 0.5)
  • 布尔值:true false
  • 空值:null
  • 列表——用空格或者逗号分隔的一组值1.5em 1em 0 2em, Helvetica, Arial
  • map——用小括号扩起的一组键值对集合($key1: value1, $key2: value2, …)
  • arglist——参数列表,函数中的变长参数

变量

  1. 定义变量:$var_name : value;

    SASS中变量的定义是宽松的,如果拿高级写的语言来考量的话会有时而是字符串时而是数字的疑惑,所以不要那么做,你不需要讲过多的注意力类型这一概念上。

    $grayColor : darken(#FFFFFF, 20%);
    $width : 42px;
    
  2. 使用变量:SASS中的变量先声明后引用,(下文中引用到的变量$widht, #grayColor在上文中已经声明,本文以此缩短排版,这并不严谨有时有点滥用需要结合上下文)

    div {
      color: $grayColor;
      width: $width;
    }
    

    上面是SCSS代码,下面是对应的CSS代码,全文如不特殊说明一律采用这种方式

    div {
      color: #cccccc;
      width: 42px;
    }
    
  3. 变量的!default关键字(前面的不能省)

    !default关键字表示:为该变量设置默认值,如果该变量已经声明过,则不改变原来值。

    $var1: 12;
    $var1: 24 !default   // var的值保持12不变
    
    $var2: 24 !default   // 直接声明并定义一个变量$var2,初始化值为24
    
  4. 局部变量全局变量

    类似于大多数语言一样,SASS中拥有局部变量与全局变量的概念,这么做可以避免变量名重复,引用或更改到了不想更改的其它变量,造成系统的混乱。不包含在选择器,函数等块级结构之内,直接在文件中声明的变量称之为全局变量,反之则为局部变量。

    $color: red;     //全局变量
    .blk {
      color: $color; //引用全局的$color,值为red
    }
    em {
      $color: orange;
      div {
        color: $color;   //引用局部的$color,值为orange
      }
    }
    
    .blk {
      color: red;
    }
    
    em div {
      color: orange;
    }
    

列表

CSS中存在有margin: 10px 15px 0 0这类属性,为了便于处理这类情况SASS中存在有列表的数值类型,有点类似于大多数语言中的数组,列表需要将不同的类型的值用逗号或者空格分隔开,对于列表,SASS提供了一些函数进行处理:

$margins: 2px 4px 0 0;

.btn {
  margin-top: nth($margins, 1); //列表的下标从1开始计算
}
.btn {
  margin-top: 2px;
}

运算符

  1. +

    加法可以用于基本的数字相加,字符串连接

    $width: 1px + 2in;
    $str: 'Hello ' + world;
    $margins: 12 12 12 1;
    
    .btn {
      width: $width + 4pt;
      font: $str;
      margin: margins + 2;
    }
    
    .btn {
      width: 198.33333px;    //不同的单位之间可以相加,但是不兼容的类型是不可以的,比如1px + 2em
      font: "Hello world";   //加法可以用于字符串的连接
      margin: margins2;
    }
    

    TIPS: +用于字符串连接时结果是否有引号跟加号左边的值保持一致,结果中的引号都会是双引号(如果想去掉可以加一层#{},或者使用unquote($string)函数),而数字,列表等类型跟字符串连接之前会被转换成有引号字符串。结果是否有引号的规则还是按照前面所述。

  2. -

    减号自然不必多说,用于数值之间的减法,也需要操作数相互兼容,与+不同,-不支持字符串操作。

  3. *

    乘号需要左右两个操作数至少有一个不带单位,不然会产生错误

    .box {
      width: 10px * 2;
      height: 4 * 5pt;
      //height: 4pt * 5pt, 这么写会报错
    }
    
    .box {
      width: 20px;
      height: 20pt;
    }
    
  4. /

    除法有些特殊,因为在CSS中/已经挪作他用,所以在下列几种情况中才会有正常的表现,不然会作为CSS直接编译。

    • ()扩起来:(100px / 2)
    • 在表达式中:1px + 100px / 2 $width / 4
    // xxx.scss
    .btn {
     width: 100px /2;
    }
    
    // xxx.css
    .btn {
        width: 100px /2; //这里的除法被原封不动的保存了
    }
    
  5. == != > < >= <=

    基本的布尔运算返回值为falsetrue

  6. if($condition, $if-true, $if-false)

    其实if不是一个运算符而是一个函数,类似于c语言中的条件运算符,if函数当$condition为真返回$if-true,否则返回$if-false,注意这里的if不同于控制流中的@if

注释

注释有以下两种风格

//这一段注释并不会显示在生成的CSS文件中
/*这一段注释会显示在生成的CSS文件中*/

嵌套

  1. 选择器嵌套,这里的选择器是CSS选择器

    选择器嵌套针对的是标签的父子(包含)关系,如果B标签在A标签的内部,那么使用选择器嵌套语法再好不过,需要注意的是嵌套对可读性的影响,避免滥用选择器的嵌套。

    现在有一段HTML:

    <body>
     <div>
         <a href="##">Item1<a>
         <a href="##">Item2<a>
         <a href="##">Item3<a>
     </div>
    </body>
    
    // xxx.scss
    div {
      a {
        color: red;
        body & { //这里的&表示当前块"div a"
                     //body在&的前面,需要提出到全局去解析,不然是没有意义的
                     //也就是说这里是"body div a",而不是"div a body div a"
          color: green;
        }
      }
    }
    
    // xxx.css
    div a {
      color: red;
    }
    body div a {
      color: green;
    }
    
  2. 属性嵌套

    属性嵌套针对border-top这类使用-分割的属性,可以使用嵌套凸显层次性。

    .banner {
      border: {  //注意border后面的":"
        top: 1px solid red;
        bottom: 2px solid green;
      }
    }
    
    .banner {
      border-top: 1px solid red;
      border-bottom: 2px solid green;
    }
    
  3. 伪类嵌套

    伪类嵌套很类似于选择器嵌套,需要借助&

    .banner {
      &:before, &:after {
        content: "";
        display: block;
      }
    }
    
    .banner:before, .banner:after {
      content: "";
      display: block;
    }
    

Mixin宏

可以使用“混入宏”打到样式的复用的目的

  1. 定义混入宏

    • 不带参数

      @mixin foo_bar {   //foo_bar为宏的名字
        -webkit-border-radius: 1px;
        -border-radius: 1px;
      }
      
    • 带参数

      @mixin foo_bar_with_arg($radius: 1px) { //参数$radius默认值1px
        -webkit-border-radius: $radius;
        -border-radius: $radius;
      }
      
  2. 使用混入宏

    div {
      @include foo_bar_with_arg(2px);
    }
    
    div {
      -webkit-border-radius: 2px;
      -border-radius: 2px;
    }
    

继承

SASS通过@extend关键字使用继承,继承可以复用已存在的样式块。

.button {
  border: 1px;
  font-size: 1.5em;
}
.btn {
  background-color: red;
  @extend .button;
}
.button, .btn { //相对于@Mixin直接的文本替换,@extend继承显得更加智能,生成的CSS更简洁
  border: 1px;
  font-size: 1.5em;
}
.btn {
  background-color: red;
}

占位符%placeholder

如果我需要继承一些CSS但是这些CSS不单独存在某些标签里该怎么办?

%baz {  //不使用@extend调用的话%placeholder并不产生任何CSS代码
  margin-top: 5px;
}
.btn {
  @extend %baz;
  margin-bottom: 10px;
}

#context a%foo {    //这种诡异的形式也不会直接产生代码,需经过@extend
  color: red;
  width: 42;
}

.someots {
  @extend %foo;
}
.btn {
  margin-top: 5px;
}

.btn {
  margin-bottom: 10px;
}

#context a.someots {
  color: red;
  width: 42;
}

插值#{}

插值是另一种本地替换的方式,有些类似于C语言中的宏定义

$arr: (top, bottom);
.btn {
  @each $item in $arr { //暂未提及这里的@each in循环结构
    margin-#{$item}: 42px;
  }
}
.btn {
  margin-top: 42px;
  margin-bottom: 42px;
}

TIPS: 插值中又一点需要特别注意的是,所有的 <u>有引号字符串</u> 经过插值会转化为 <u>无引号字符串</u>

流程控制

  1. @if

    .block {
      @if 2 >= 3 {
        width: 200px;
      }
      @elseif 2 > 1 {
        width: 100px;
      }
      @else {
        width: 300px;
      }
    }
    
    .block {
      width: 100px;
    }
    
  2. @for

    for循环有两种格式,分别以through,to两个关键字区分,for循环可以生成一个范围区间,并绑定一个变量给用户。

    for $i from <start> through <end>: $i从<start>到<end>(不包括<start>)

    for $i from <start> through <end>: $i从<start>到<end>(包括<end>)

    @for $i from 1 through 3 {
      .block-#{$i} {
        width: 100px * $i;
      }
    }
    
    .block-1 {
      width: 100px;
    }
    
    .block-2 {
      width: 200px;
    }
    
    .block-3 {
      width: 300px;
    }
    

    循环可以极大的缩短CSS的代码量,有时CSS中的选择器可以达到效果,但是更多场景下灵活的SCSS利用循环可以极大的提高效率。

  3. @while

    @while用一个布尔量来决策循环是否结束。

    $i: 1;
    @while $i <= 3 {
      .block-#{$i} {
        width: 100px * $i;
      }
      $i: $i + 1;
    }
    
    .block-1 {
      width: 100px;
    }
    
    .block-2 {
      width: 200px;
    }
    
    .block-3 {
      width: 300px;
    }
    
  4. @each

    @each $var in <list>: 遍历一个列表,绑定列表中的值到$var上。

    $nums: red yellow green;
    @each $color in $nums {
      .#{$color}_div {
        color: $color;
      }
    }
    
    .red_div {
      color: red;
    }
    
    .yellow_div {
      color: yellow;
    }
    
    .green_div {
      color: green;
    }
    

常用函数

  1. unquote($string) quote($string)

    这两个函数分别为字符串去除引号(只去除两端),添加双引号。

  2. to-upper-case($string) to-lower-case($string)

    将字符串全部转换成大/小写。

  3. 一些数值函数

    percentage($value): 将不带单位的数转换成百分数

    round($value): 将数值四舍五入

    ceil($value): 返回一个不小于$value的整数

    floor: 返回一个不大于$value的整数

    abs($value): 返回$value的绝对值

    min($numbers...): 返回列表中最小的值

    max($numbers...): 返回列表中最大的值

    random(): 获取一个随机数

  4. 一些列表函数

    length($list): 返回列表长度

    nth($list, $n): 返回列表的第n个值

    join($list1, $list2, $separator: auto|comma|space): 合并两个列表

    append($list, $val, $peparator: auto|comma|space): 为列表追加值

    zip($lists...): 将多个列表压缩成多维度列表

    index($list, $val): 找到第一个与$val相等的值在$list中的下标p

  5. 一些map函数

    map-get($map, $key): 取得$map中$key键对应的值,没有则返回null

    map-has-key($map, $key): 判断$map中是否有键$key

    map-keys($map): 返回$map中键的列表

    map-values($map): 返回$map中值的列表

    map-merge($map1, $map2): 返回包含$map1与$map2中所有键值对的一个新map

    map-remove($map, $key): 返回从$map中移除了$key为键的键值对的map

    keywords($args...): 按照给定的参数动态创建mapkeywords(c1: #fff, c2: #000)

  6. 内省函数

    type-of($value): 返回值的类型

    unit($number): 返回数值的单位

    unitless($number): 判断值是否有单位

    comparable($number-1, $number-2): 判断两个值是否可以相互比较

  7. 颜色函数

    rgb($red, $green, $blue): 生成RGB颜色

    rbga($red, $green, $alpha): 生成RGBA颜色

    rgba($color, $alpha): 返回$color改变透明度为$alpha之后的颜色

    red($color): 获取$color的红色分量

    green($color): 获取$color的绿色分量

    blue($color): 获取$color的蓝色分量

    mix($color-1, $color-2, $weight: 0.5): 混合两种颜色

    invert($color): 返回$color的反向色,rgb反向,alpha不变

    hsl: 生成HSL颜色

    hsla: 生成HSLA颜色

    hue($color): 返回$color的色相

    saturation($color): 返回$color的饱和度

    lightness($color): 返回$color的亮度

    adjust-hue($color, $degrees): 调整色相adjust-hue(#234f33, 45deg)

    lighten($color, $amount): 变量颜色

    darken($color, $amount): 变暗颜色

    saturate($color, $amount): 增强饱和度

    desaturate($color, $amount): 降低饱和度

    grayscale($color): 返回$color对应的灰色

    complement($color): 返回与$color色相相反的颜色

    alpha($color): 获取透明度

    opacity($color): 获取透明度

    opacify($color, $amount): 降低透明度

    fade-in($color, $amount): 降低透明度

    transparentize($color, $amount): 增加透明度

    fade-out($color, $amount): 增加透明度

自定义函数

使用@function关键字定义函数,可以问函数提供一个参数列表,在其中可以设置缺省参数,或者变长参数,如果函数有返回值需要使用@return关键字。

@function foo($arg1, $arg2: 42, $args...) { //$arg2有默认值42,$args为变长参数
  @debug 'foo get $arg1: ' + $arg1;
  @debug 'foo get $arg2: ' + $arg2;
  @debug 'foo get $args: ' + $args;
  @return 0;
}
.btn {
  width: foo(234, 43, 234, 2, 34, 234)
}
/*
控制台输出
DEBUG: foo get $arg1: 234
DEBUG: foo get $arg2: 43
DEBUG: foo get $args: 234, 2, 34, 234
*/

@规则

SASS支持所有的CSS的@规则,以及一些自己的扩展,也称为指令(directives)

  1. @import

    SASS扩展了CSS的@import规则,可以导入其他的SCSS文件,寻找文件的路径可以是当前目录,或者通过:load_path, —load-path配置

    以下几种情况@import命令编译为CSS原生规则

    • 导入文件扩展名为.css
    • 导入文件名以http://开头
    • 文件名为url()
    • 如果@import包含媒体查询
    @import "foo.css";               //后缀为css会编译为原生规则
    @import "foo.scss";
    @import "foo";                   //导入文件可以不写后缀
    @import "filea", "fileb";        //导入多个文件
    @import "_fileignorecompile" //文件名之前加上_则只导入文件,不进行编译
    
  2. @media

    SASS中的@media可以嵌套在CSS规则中

       .block {
         width: 100px;
         @media screen and (orientation: landscape) {    //@media会浮出到最外层
           width: 200px;
         }
       }
    
       //@media 是可以嵌套的
       $media: screen;
       @media #{$media} {    //在@media中使用插值
         .btn {
           @media (orientation: landscape) {
             width: 500px;
           }
         }
       }
    
       .block {
         width: 100px;
       }
       @media screen and (orientation: landscape) {
         .block {
           width: 200px;
         }
       }
    
       @media screen and (orientation: landscape) {
         .btn {
           width: 500px;
         }
       }
    
  3. @at-root

    at-root可以让选择器跳出到嵌套中

    .foo {
      color: red;
      
      .bar {
        color: blue;
        
        @at-root .baz {
          color: white;
        }
      }
    }
    
    .foo {
      color: red;
    }
    .foo .bar {
      color: blue;
    }
    .baz {   //跳出了嵌套,不在层级结构中
      color: white;
    }
    
  4. @debug @warn @error

    用于向控制台输出不同信息

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

推荐阅读更多精彩内容

  • 基础 声明变量 普通变量 默认变量 变量覆盖:只需要在默认变量之前重新声明下变量即可 变量的调用 局部变量和全局变...
    Jill1231阅读 1,268评论 0 1
  • 1、SCSS 是 Sass 的新语法格式,从外形上来判断他和 CSS 长得几乎是一模一样,代码都包裹在一对大括号里...
    夜幕小草阅读 1,700评论 2 10
  • 再谈CSS 预处理器2016-09-09 Justineo JavaScript转自:http://efe.bai...
    抓住时间的尾巴吧阅读 1,545评论 0 2
  • CSS 预处理器技术已经非常的成熟,而且也涌现出了越来越多的 CSS 的预处理器框架。本文向你介绍使用最为普遍的三...
    Mx勇阅读 1,295评论 0 7
  • 如果付出了真 被回馈的是伤的深 又何必假装 假如爱不能满分 又何必赠与伤痕 如果爱情的火焰熄灭 就不必再有余温 因...
    会哭de石头阅读 174评论 0 1