Sass

简介

CSS预处理器

  • SASS:Syntactically Awesome Stylesheets
  • SCSS:Sassy CSS
  • .scss/.sass文件经过Sass编译转换成.css文件

编译

Sass 命令语法:sass [options] [input] [output]

环境

> ruby -v        # 依赖ruby
> gem install sass    # 安装sass
> sass -v

转译

> sass test.scss test.css
> sass --style compressed test.scss test.css

输出样式的风格可以有四种选择,默认为nested

  • nested:嵌套缩进的css代码
  • expanded:展开的多行css代码
  • compact:简洁格式的css代码
  • compressed:压缩后的css代码

监听并自动转译

> sass --watch sass/style.scss                  #监听sass/style.scss,转译到sass/style.css
> sass --watch sass/style.scss:css/style.css    #监听sstyle.scss,转译到css/style.css
>  sass --watch sass/:css                       #监听sass目录,转译到css目录下

监听并开启SourceMap功能

>  sass --watch --scss --sourcemap style.scss:style.css
  • --scss:表示使用的SCSS语法格式
  • --sourcemap:表示生成对应的.map文件

基于nodeJS使用

示例:监听转译./src/sass/style.scss文件

gulpfile:

var gulp=require("gulp");
var sass = require('gulp-sass');
function sassBuild(opts,filename){
    var sassOptions = {
      errLogToConsole: true,
      outputStyle: 'expanded',
      loadPath:opts.loadPath
    };
    function build(event){
        if(event)
            console.log('File ' + event.path + ' was ' + event.type);
        gulp.src(opts.src+"/"+filename+".scss")
            .pipe(sass(sassOptions).on('error', sass.logError))
            .pipe(gulp.dest(opts.dest));
    }
    build();
    gulp.watch(opts.src+"/**/*.scss",build);
}

gulp.task('sass', function () {
    var opts={
        src:"./src/sass",
        dest:"./public",
        loadPath:"./src/sass"
    };
    sassBuild(opts,"style");
});

执行:

> gulp sass

Sass语法

注释

/* 多行注释,会出现在输出css中 */
/*! 重要的注释,例如版权信息,作者,补丁的说明等(会出现在输出css中) */
// 单行注释 ,私人的注释 (不会出现在输出css中)

导入

@import 导入样式文件 (可不加文件扩展名,默认加载.scss,.sass文件)

// Import other files 
@import "reset.scss";
@import "variables.scss";
@import "mixins.scss";

// Site-specific styles
.foo { … }

变量

  • 可复用
  • 定义:

    • $变量名:变量值
    • $变量名:变量值 !default; 默认变量
    • 多值变量:
      • $变量名: 值1 值2 ...
      • $变量名: ((值1,值2),(值3,值4,...),...)
      • 与JS不同,索引从1开始
      • 使用,分隔列表项;
      • 使用()进行列表嵌套(不要超过五层);
      • 建议使用()初始化列表,而不是null;
      • 注意字符串需添加引号;
  • 调用:

    • $变量名
    • #{$变量名}(在字符串中引用变量,需写在#{}中)
  • 在css输出文件中将会用变量值进行替换

示例:

/*声明变量*/
$color: #333;
$bgcolor:#f36;

/*引用变量*/
body {
    color: $color;
    background-color: $bgcolor;
}
//多值变量
$list : ();
$list : #b4d455,42,"awesome";
$list : (#b4d455,42,"awesome");
$list : (("a1","a2"),("b1","b2"));
$list : "a1" "a2","b1" "b2";    //using different separators to distinguish levels

嵌套

嵌套规则

  • 嵌套:通过嵌套的层级关系来简化选择器中重复出现的每个元素
  • 嵌套命名空间:将样式属性中共同的命名空间部分提取出来共享
  • 使用&这个特殊占位符替代当前父层选择器

示例1:

section { 
    margin: 10px; 
    nav {
        height: 25px;
        >a {
            color: #0982c1;
            &:hover{
                text-decoration: underline;
            }
        }
    }
}

=> css

section {margin: 10px;}
section nav {height: 25px;}
section nav>a {color: #0982c1;}
section nav>a:hover {text-decoration: underline;}

示例2:

section.main p { 
    margin: 0 0 20px 0; 
    font-size: 18px; 
    line-height: 1.5; 
    body.store & { font-size: 16px; line-height: 1.4; }
}

=> css

section.main p { margin: 0 0 20px 0; font-size: 18px; line-height: 1.5; }
body.store section.main p { font-size: 16px; line-height: 1.4; }

复用样式块

定义复用样式块

  • @mixin
    • 创建动态规则(可根据上下文变量发生变化),本身不会输出到css中
    • 相当于一个函数,可以:
      • 传递参数
      • 传递样式(使用@content占位符代表动态传递进来的一段样式)
      • 设置变量
    • 使用@include调用
      @mixin 名称($参数名:参数值){
         /*样式规则*/
         ...
         @content;
      }
      
  • %
    • 创建静态规则,本身不会输出到css中
    • 不能传递参数,设置变量
    • 使用@extend调用
      %名称 {
         /*样式规则*/
      }
      
  • .class
    • 创建静态规则,本身会输出到css中
    • 不能传递参数,设置变量
    • 使用@extend调用
      .名称 {
         /*样式规则*/
      }
      

调用复用样式块

  • @include
    • 用来调用@mixin定义的函数模块
    • 产生的样式是以复制拷贝的方式存在的
    • 多次调用同一个@mixin,编译出的CSS不会对其进行合并
      选择器{
         @include mixin名(参数值);
      }
      
  • @extend
    • 用来调用.class或者%placeholders定义的属性模块
    • 产生的样式是以组合申明的方式存在
    • 多次调用同一个%Placeholders.class,编译出的CSS会对其进行合并
      选择器 {
         @extend .xxx
         @extend %xxx
      }
      

使用示例

  • @mixin + @include

     @mixin error($borderWidth:2px){
         border: $borderWidth solid #f00;
         color: #f00;
     }
    
     /*引用定义好的errorMixins:*/
     .generic-error {
         @include error();
     }
     .login-error {
         @include error(3px);
         font-size:13px;
     }
     .test-error{
         @include error($testColor:5px);
         font-size:10px;
     }
    

    => css

     .generic-error {
         border:2px solid #f00;
         color: #f00;
     }
     .login-error { 
         border: 3px solid #f00;
         color: #f00;
         font-size:13px;
     }
     .test-error{
         border: 5px solid #f00;
         color: #f00;
         font-size:10px;
     }
    
  • @mixin+@content+@include

      @mixin error($borderWidth:2px){
          border: $borderWidth solid #f00;
          color: #f00;
          @content;
      }
      .generic-error {
          @include error(){background:#333;}
      }
      .login-error {
          @include error(3px){background:#eee};
          font-size:13px;
      }
    

    =>css

      .generic-error {
          border:2px solid #f00;
          color: #f00;
          background:#333;
      }
      .login-error { 
          border: 3px solid #f00;
          color: #f00;
          font-size:13px;
          background:#eee;
      }
    
  • .class + @extend

     .block {
         margin: 10px 5px;
         padding:2px;
     }
    
     p {
         @extend .block;
         border: 1px solid #eee;
     }
     ul,ol {
         @extend .block;
         color:#333;
         text-transform: uppercase;
     }
    

    => css

     .block,p,ul,ol {
         margin: 10px 5px;
         padding:2px;
     }
     p {
         border: 1px solid #eee;
     }
     ul,ol{
         color: #333; text-transform: uppercase;
     }
    
  • % + @extend

      %block {
          margin: 10px 5px;
          padding:2px;
      }
    
      p {
          @extend %block;
          border: 1px solid #eee;
      }
      ul,ol {
          @extend %block;
          color: #333;
          text-transfomr:uppercase;
      }
    

    => css

      p, ul, ol { 
          margin: 10px 5px; 
          padding: 2px; 
      }
      p {
          border: 1px solid #eee;
      }
      ul, ol {
          color: #333;
          text-transfomr: uppercase;
      }
    
  • @mixin + %Placeholders

      %grid {
          box-sizing: border-box;
          display: inline-block;
      }
      @mixin grid($width: 1){
          @extend %grid;
          width: percentage($width);
      }
    
      .grid-half{
          @include grid(1/2);
      }
      .grid-whird{
          @include grid(1/3);
      }
    

    => css

      .grid-half, .grid-third {
        box-sizing: border-box;
        display: inline-block;
      }
      .grid-half {
        width: 50%;
      }
      .grid-third {
        width: 33.33333%;
      }
    

逻辑处理

循环

  • @for
    • 关键字through表示包括end这个数
      //[start,end]
      @for $i from $start through $end {
        ...
      }
      
    • 关键字to表示不包括end这个数
      //[start,end)
      @for $i from $start to $end {
        ...
      }
      
  • @each
      @each $var in $someList { 
          ...
      }
    

示例:

$slider-list:(red,green ,blue,yellow);

//使用@for
@for $i from 1 through length($slider-list){
  .slider-# {$i}{
    background:nth($slider-list ,$i);
  }
}

//使用@each
@each $color in $slider-list{
  $index: index($slider-list ,$color);
  .slider-# {$index}{
    background:$color;
  }
}

判断

  • @if,@else if,@else
      @if 条件1{
          ...
      }@else if 条件2{
          ...
      }@else{
          ...
      }
    
      //三目判断:第一个表示条件,第二个表示条件为真的值,第三个表示为假的值
      if($condition, $if-true, $if-false)
    
  • 条件:
    • not,or,and分别表示非,或,与
    • ==,!=分别表示等于与不等于

示例:

@if not($a){
    p{
        color:red;
    }
}
body {
    @if $theme == red {
        background: rgba(255, 0, 0, 0.5);
    } @else if $theme == yellow {
        background: rgba(255, 255, 0, 0.5);
    } @else if $theme == black {
        background: rgba(0, 0, 0, 0.5);
    }
}
$fontBold: true;
.title {
    font-weight: @if($fontBold, bold, normal);        //bold
}

function

@function:返回一个值(值只有放在变量或作为属性值才正确)

@function 名字(参数){
    @return 值
}

示例:

// px转em
@function pxToEm($px, $base: 16) {
    @return ($px / $base) * 1em;
}

p{
    font-size:pxToEm(20);
}

附:Sass内置的一些函数

  • darken($color,precent)
  • lighten($color,precent)
  • length($list):返回列表变量长度(如果不是list,返回1)
  • index($list,$value):返回索引值
  • nth($list,$index):获取索引所在项
  • append($list,$value[,$separator]):添加值
  • join($list1,$list2[,$separator]):合并
  • zip(*$lists):组合成一个多维列表(列表长度将以最短的一个为准)