Sass 是CSS的一种扩展语言,它允许您使用 变量、嵌套、函数、继承 等,并且完全兼容CSS语法。传统的CSS只是一种描述性的语言,只能通过一行行的描述来定义样式,而 Sass 能以类似于 JavaScript 的编程方式来定义样式。类似于 Sass 的 CSS 预处理器还有 Less,不过 Sass 貌似使用的要更多一些。

安装

Sass 官网: https://sass-lang.com/

要使用 Sass 还需要下载安装 Sass 的编译器,因为浏览器并不认识 Sass,需要编译器编译为 CSS 后才能给浏览器使用。Sass 可以通过 npm 来安装,输入:

npm install -g sass

使用 npm 需要安装 Node,安装完成后输入: sass --help 可以查看帮助信息。Sass 的文件后缀为 sass 或 scss,如果直接在 HTML 文件中引入 sass 或 scss 是无法使用的,需要先编译为 CSS,然后在 HTML 文件中引入编译后的 CSS 文件才能使用。

编译

因为 Sass 需要编译后才能预览效果,所以把编译写在前面。下面把名为 input.scss 的文件编译为 output.css

sass input.scss output.css

上面使用的是相对路径,而且两个文件都在同一目录下,编译完成后再 HTML 文件中引入编译后的 CSS 文件就可以使用了。

如果需要在编译的时候压缩文件可以使用:

sass --style=compressed demo1.scss demo1.css

使用 --style=compressed 选项后所有 CSS 语句会被编译为一行,并且会去除注释和多余的空格,适合用于生产环境。

如果你在编写的时候想预览效果,但又不想每次预览都输入编译命令的话可以使用 --watch 来监听文件,当监听的 sass 或 scss 发生变化时Sass就会把 sass 或 scss 编译为 CSS,下面监听 demo1.scss ,当 demo1.scss 发生变化时就会编译为 demo1.css

sass --watch demo1.scss demo1.css

上面的 demo1.scss 发生变化时 demo1.css 也会同步发生变化。

GUI 编译器

如果不想用 Sass 官方的命令行编译器的话 也可以选择第三方开发的带图形界面的 Sass 编译器,下面是一些带图形界面的 Sass 编译器:

其中一部分编译器是同时支持 Sass 和 Less 的。

语法

Sass和SCSS区别

Sass 的语法有两种,一种是传统的 Sass 语法,一种是 SCSS 的语法,SCSS 是 Sass3 中引入的一种新的语法,更接近于 CSS 的语法,下面是两种语法的对比:

SCSS

.button {
    padding: 3px 10px;
    font-size: 12px;
    border-radius: 3px;
    border: 1px solid #e1e4e8;
}

Sass

.button
    padding: 3px 10px
    font-size: 12px
    border-radius: 3px
    border: 1px solid #e1e4e8

Sass 去除了 CSS 中的花括号和分号,语句之间用换行符分隔,Sass 的文件后缀为: .sass ,SCSS 的后缀为: .scss ,其他区别不大,本篇文章主要以 SCSS 为主。

本篇文章演示的语法以 SCSS 为主,在介绍的时候会以 Sass 来介绍,但是在代码演示区域一般是 SCSS,如果是 Sass 演示,在代码区域上方会有说明。

在 SCSS 中注释可以使用 ///**/ ,如果使用 // 在编译为CSS后会被删除,如果使用 /**/ 在编译为 CSS 后会被保留,Sass 也是一样的,如果编译为压缩的 CSS 所有注释都会被删除,如果要在压缩的 CSS 中保留注释可以在注释内容的开头加一个 ! ,下面是注释的写法:

SCSS

//  单行注释,在编译为CSS时会被删除
/*多行注释,在编译为压缩的CSS时会被删除*/
/*! 在编译为压缩的CSS时不会被删除,可以用来写许可信息*/

div {
    width: 100px;
}

嵌套

在 SCSS 中可以使用类似于 HTML 嵌套的方式来定义样式,下面是一段简单的 HTML:

HTML

<div id="box">
    <h1>标题</h1>
    <p>Hello</p>
    <a href="javascript:;">链接</a>
</div>

下面通过嵌套的方式给 div 中的 h1pa 定义样式:

SCSS

#box {
    h1 {
        color: #0000FF;
    }
    p {
        color: #008080;
        font-size: 18px;
    }
    a {
        background: #FF5080;
        color: #ffffff;
    }
}

如果是 Sass 就去除花括号和分号,下面是编译为 CSS 后的效果:

CSS

#box h1 {
  color: #0000FF;
}
#box p {
  color: #008080;
  font-size: 18px;
}
#box a {
  background: #FF5080;
  color: #ffffff;
}

对于层级较深的元素来说使用嵌套的可读性要更好。

变量

Sass的变量很简单,变量名开头使用 $ ,变量可以在属性值使用,如下:

SCSS

//  变量
$w: 200px;
$h: 200px;
$color: #FFA8FF;

#box {
    width: $w;
    height: $h;
    background: $color;
}

下面是编译的 CSS :

CSS

#box {
  width: 200px;
  height: 200px;
  background: #FFA8FF;
}

在最外层声明的变量为全局变量,全局变量在任何地方都能访问,包括引入的其他文件。声明在花括号内的变量为局部变量,只有变量所在括号内才能访问。下面是局部变量:

SCSS

#box {
    //  局部变量
    $w: 200px;
    $h: 200px;
    $color: #FFA8FF;
    width: $w;
    height: $h;
    background: $color;
}

Sass 如下:

Sass

#box
    //  局部变量
    $w: 200px
    $h: 200px
    $color: #FFA8FF
    width: $w
    height: $h
    background: $color

Sass允许全局变量和局部变量的名称相同,如果出现相同名称的全局变量和局部变量在局部变量范围内会使用局部变量。

@import 引入

在 Sass 中可以使用 @import 引入 Sass、SCSS 、CSS 文件,下面是一个包含字体样式的 font.scss 文件:

SCSS

* {
    font-size: 18px;
    font-family: 楷体;
    text-shadow: 5px 5px 5px #000000;
}

下面引入 font.scss

//  导入font
@import 'font';

#box {
    width: 200px;
    height: 200px;
    background: pink;
}

所有导入的文件最终都会被编译为一个 CSS,文件名可以使用相对路径,不需要后缀名。

·@import· 也可以写在花括号里,如果写在花括号里只有当前所在括号的子元素有效果,相当于局部引入,下面是一个 HTML:

HTML

<div id="box">
    <p>Hello Sass</p>
</div>
<p>Gooe Afternone</p>

下面在 #box 的区域内引入 font.scss

SCSS

#box {
    //  导入font
    @import 'font';
    width: 200px;
    height: 200px;
    background: pink;
}

只有 #box 里的 p 有效果,#box 下面的 p 不会有效果,下面是编译后的 CSS:

CSS

#box {
  width: 200px;
  height: 200px;
  background: pink;
}
#box * {
  font-size: 18px;
  font-family: 楷体;
  text-shadow: 5px 5px 5px #000000;
}

Sass 除了能引入 Sass 和 SCSS 外也能引入 CSS,引入 CSS 的文件名不能包含后缀名,CSS 文件中不能包含 Sass 和 SCSS 的功能。

@mixin

使用 Mixins可以把一组常用的样式封装起来,需要的时候可以直接调用,类似于 。下面封装一组常用样式:

SCSS

//  封装
@mixin box {
    width: 200px;
    height: 200px;
    background: pink;
    border-radius: 50%;
}

#box {
    //  直接调用
    @include box;
}

也可以使用嵌套:

@mixin list {
    list-style: none;
    background: #FFFF00;
    padding: 10px;
    li {
        background: #5830E0;
        color: #ffffff;
        margin: 0;
        padding: 5px 0;
        text-align: center;
    }
}

ul {
    @include list;
}

Mixins 也可以使用参数,在封装的时候可以用变量来指定参数,调用的时候也需要向函数一样的传入参数,如下:

SCSS

@mixin box($color, $margin, $w, $h) {
    #{$color}: pink;
    margin: $margin;
    width: $w;
    height: $h;
}

#box {
    @include box(background, 20px auto, 200px, 200px);
}

也可以定义默认参数,调用的时候可选择省略参数:

SCSS

@mixin box($color, $margin, $w: 500px, $h: 500px) {
    #{$color}: pink;
    margin: $margin;
    width: $w;
    height: $h;
}

#box {
    @include box(background, 20px auto);
}

类似于ES6的函数默认参数。

@function

函数允许您封装更复杂的操作,下面是一个简单的函数:

SCSS

//  一个简单的函数
@function box($w) {
    $h: $w * 3;
    //  返回计算后的值
    @return $h;
}

#box {
    width: 200px;
    height: box(200) + px;
    background: pink;
}

上面的函数就是根据传入的宽度计算出高度,高度是宽度的 300%,然后返回高度。其中的 @return 就类似于 JS 函数的返回,每个函数都必须包含 @return ,函数的参数也可以设置默认参数,调用的时候可以选择省略参数。

如果是 Sass 的函数就去除花括号和分号,注意缩进。

@extend

extend 也就是继承,通过 @extend 可以直接继承其他元素的样式,如下:

SCSS

#box1 {
    width: 200px;
    height: 200px;
    background: pink;
}

#box2 {
    @extend #box1;
    border-radius: 50%;
}

在继承其他元素样式的同时也能保留自己的样式,下面是编译后的 CSS :

CSS

#box1, #box2 {
  width: 200px;
  height: 200px;
  background: pink;
}

#box2 {
  border-radius: 50%;
}

@debug

@debug 可以用来输出变量或表达式的值,调试专用,内容会在终端输出,用法如下:

SCSS

@debug 20 * 30 * 2;
$color: #c0c0c0;
@debug $color;

流程控制

@if

这里的 @if 和 JS 里的 if 差不多,如果为 真 返回 true 否则返回 false ,用法如下:

SCSS

@mixin box($border) {
    width: 200px;
    height: 200px;
    background: pink;
    //  是否需要设置边框
    @if $border {
        border: 1px solid #000000;
    }
}

#box{
    @include box(true);
}

上面把 @mixin@if 搭配使用,如果参数为 true 就设置边框,否则就不设置边框。

如果是 Sass 就去除花括号,但要注意缩进。

@else

这里的 @else 还是和 JS 的 else 差不多,需要配合 @if 使用,用法如下:

SCSS

@mixin box($red-background) {
    width: 200px;
    height: 200px;
    //  如果 $red-background 为 true 就设置红色背景,否则就设置粉色背景
    @if $red-background {
        background: red;
    } @else {
        background: pink;
    }
}

#box{
    @include box(false);
}

上面的 $red-background 参数如果为 true 就设置背景颜色为红色,否则就设置背景颜色为粉色。

@else if

@else if 需要搭配 @if 使用,类似于 JS 的多条件判断,用法如下:

SCSS

@mixin box($font-size: max) {
    //  根据传入的参数来设置字体大小
    @if $font-size == max {
        font-size: 100px;
    } @else if $font-size == medium {
        font-size: 50px;
    } @else if $font-size == mini {
        font-size: 12px;
    } @else {
        font-size: 18px;
    }
}

#box{
    @include box(mini);
}

上面根据传入的参数来设置字体大小,如果参数不符合要求就使用默认设置。

@each

使用 @each 您可以同时给列表中的多个元素设置样式,用法如下:

HTML

<div id="box-100px">100</div>
<div id="box-200px">200</div>
<div id="box-300px">300</div>

上面是 3 个 div id 分别为: #100px#200px#300px,下面用 @each 给 3 个 div 设置样式:

SCSS

$sizes: 100px, 200px, 300px;

@each $size in $sizes {
    #box-#{$size} {
        font-size: $size;
    }
}

上面分别给 3 个 div 设置字体大小,下面是编译后的 CSS:

CSS

#box-100px {
  font-size: 100px;
}

#box-200px {
  font-size: 200px;
}

#box-300px {
  font-size: 300px;
}

@for

类似于 JS 的 for 循环,用法如下:

SCSS

@for $i from 1 to 4 {
    ul li:nth-of-type(#{$i}) {
        width: $i * 100px;
        height: $i * 100px;
        border: $i + px solid #000000;
    }
}

上面的 $i 相当于计数器,1 to 4 就是循环开始和停止的位置,每次循环 $i 都会 +1 。下面是编译后的 CSS :

CSS

ul li:nth-of-type(1) {
  width: 100px;
  height: 100px;
  border: 1px solid #000000;
}

ul li:nth-of-type(2) {
  width: 200px;
  height: 200px;
  border: 2px solid #000000;
}

ul li:nth-of-type(3) {
  width: 300px;
  height: 300px;
  border: 3px solid #000000;
}

@while

和 JS 的 while 循环差不多,满足条件就执行,否则就不执行,用法如下:

SCSS

$i: 1;

@while $i < 4 {
    ul li:nth-of-type(#{$i}) {
        width: $i * 100px;
        height: $i * 100px;
        border: $i + px solid #000000;
    }
    $i: $i + 1;
}

下面是编译后的 CSS :

CSS

ul li:nth-of-type(1) {
  width: 100px;
  height: 100px;
  border: 1px solid #000000;
}

ul li:nth-of-type(2) {
  width: 200px;
  height: 200px;
  border: 2px solid #000000;
}

ul li:nth-of-type(3) {
  width: 300px;
  height: 300px;
  border: 3px solid #000000;
}

数据类型

Numbers

Sass 的数值可以包含单位,也可以使用科学计数法表示,50e3 表示 50 的 3 次方 也就是 5000,在计算的时候也可以包含单位。更详细的数值说明可以访问:官方文档

Strings

Sass 的字符串可以包含引号,也可以不包含引号,但是不包含引号的字符串解析时可能会有一些问题,问题说明如下:

  • CSS 颜色代码或名称会被解析为颜色。
  • null 会被解析为 Sass 的 null 空值。
  • truefalse 会被解析为 Booleans。
  • andor 会被解析为运算符。

在使用的时候还是建议加引号。如需看详细的字符串说明可以访问: 官方文档

Colors

Sass 支持多种颜色类型,如下:

SCSS

@debug #f2ece4; // #f2ece4
@debug #b37399aa; // rgba(179, 115, 153, 67%)
@debug midnightblue; // #191970
@debug rgb(204, 102, 153); // #c69
@debug rgba(107, 113, 127, 0.8); // rgba(107, 113, 127, 0.8)
@debug hsl(228, 7%, 86%); // #dadbdf
@debug hsla(20, 20%, 85%, 0.7); // rgb(225, 215, 210, 0.7)

Lists

Sass 的列表有点类似于 JS 的数组,列表中的数据可以使用逗号或空格分隔,如果需要获取列表中的数据可以使用 nth($list, $index) 获取,其中的 list 为列表、index 为索引值,索引值从 0 开始。用法如下:

SCSS

//  列表
$list: (20px, 30px, 50px, 100px, pink);

#box {
    width: nth($list, 4);
    height: nth($list, 3);
    background: nth($list, 5);
}

列表可以配合 @each@for 使用,使用 append($list, $val) 可以给列表添加内容,参数的 list 就是列表、val 就是要添加的内容,返回添加后的列表,如下:

SCSS

//  列表
$list: (100px, pink);
//  添加
@debug append($list, red);  // 100px, pink, red

append 只会返回新列表,不会修改原有列表。

如果要获取列表中某个内容的索引值可以使用 index($list, val) ,如果内容存在就返回索引值,否则返回 null ,如下:

SCSS

//  列表
$list: (100px, pink);
//  获取 pink 的索引值
@debug index($list, pink);  //  2

如果需要查看更详细的 Sass 列表说明可以访问: 官方文档

Maps

这里的 Map 有点类似于 JSON,使用键值对的方式存储,要获取值可以使用 map-get($map, $key) ,用法如下:

SCSS

//  Maps
$maps: ("w": 200px, "h": 200px, "color": pink);

#box{
    width: map-get($maps, "w");
    height: map-get($maps, "h");
    background: map-get($maps, "color");
}

Map 也可以配合 @each 使用。

如果要给 Map 添加键值对可以使用: map-merge($map1, $map2),返回添加后的 Map,如下:

SCSS

//  Maps
$maps: ("color": pink);
@debug map-merge($maps, ("d": none));  // ("color": pink, "d": none)

Booleans

和其他编程语言差不多,true 为 真、false 为 假,可以配合 @if 使用。

null

null 为空值,如果在样式属性中使用 null 该属性会被省略。

functions

可以看上面的 @function ,如果要查看官方说明可以访问: 官方文档

运算符

Sass 可以支持常用的数学运算符和其他的一些运算符,下面是简单说明:

  • == 用于检查两个值是否相同。
  • != 检查两个值是否是不相同的。
  • +、-、*、/ 数学运算。
  • <、<=、>、>= 检查两个数字是否大于或小于另一个。
  • and 并且。
  • or 或。
  • + 也可以用来连接字符串。

如果要查看更详细的说明可以访问: 官方文档

以上就是 Sass 的使用指南,这篇指南基本上涵盖了 Sass 常用的功能,如果要查看更详细的官方文档可以访问: https://sass-lang.com/documentation