sass预处理中文教程(2023开学版)

Sass安装步骤

一、Sass的安装

由于Sass是使用Ruby编写的,所以我们在使用Sass之前需要安装一下Ruby。下面是Windows平台的安装步骤。对于Mac平台,请查看这里:Mac平台安装Sass。

【步骤1“下载Ruby”】:大家到Ruby的官网(http://rubyinstaller.org/downloads)下载最新版本的Ruby版本,这里我们下载的是“Ruby2.3.1”。

sass预处理中文教程(2023开学版)_第1张图片

【步骤2“安装Ruby”】:下载好“Ruby2.3.1”之后,点击安装即可。在安装的时候,我们需要注意2点:(1)安装路径建议选择C盘;(2)安装到下面这一步时,一定一定要选择第2项,不然就会安装失败:

sass预处理中文教程(2023开学版)_第2张图片

【步骤3“下载Sass”】:安装好“Ruby2.3.1”之后,然后到这个页面(https://rubygems.org/gems/sass)上面把“Sass安装包”下载下来。我们可以在这个网页右栏找到“下载”这两个字,点击即可下载:

sass预处理中文教程(2023开学版)_第3张图片

【步骤4“打开Ruby命令端”】:在电脑的左下方点击“开始”→“所有程序”→“Ruby 2.3.1” →“Start Command Prompt with Ruby”:

sass预处理中文教程(2023开学版)_第4张图片

【步骤5】:打开Ruby命令终端之后,输入下面这个指令,把Sass安装包拖到命令指定位置会生成指定路径,然后点击“Enter回车”即可安装,如图所示:

gem install <这里把Sass安装包拖进来>

sass预处理中文教程(2023开学版)_第5张图片

【步骤6】:上面的步骤都完成后,我们需要检查Sass是否安装成功。检查的方法很简单,我们在命令终端使用“sass -v”指令,按回车后,如果显示“Sass 3.4.22 ”的字样就说明Sass安装成功:

sass预处理中文教程(2023开学版)_第6张图片

二、Sass的更新

Sass版本会不断更新,不过更新Sass并不需要像其他软件那样每次更新都需要卸载,然后再重装。在Sass中,每次更新版本,我们只需要在命令终端输入一个指令即可:

gem update sass

点击“Enter”键后,如果显示下图信息“Nothing to update”,说明Sass已经更新到最新版本了:

sass预处理中文教程(2023开学版)_第7张图片

三、Sass的卸载

在使用Sass的过程中,有时候我们会碰到一些无法解决的问题,这个时候就需要卸载Sass再重新安装Sass了。在Sass中,每次卸载,我们也只需要一个指令就能解决:

gem uninstall sass

输入命令,点击“Enter”键后,就能卸载Sass了。不过一般情况下,我们是用不着卸载这个指令的。

sass简介

一、什么是CSS预处理器?

学过CSS的小伙伴都知道,CSS只是一门描述性的语言,你只能一行一行单纯地描述,并不能像JavaScript那样使用变量、循环、运算等方式来操作。

CSS预处理器的出现,使得我们可以像操作JavaScript那样以“编程”的方式来书写CSS。在CSS预处理器中,我们可以使用变量、循环、函数等方式来简化操作,提高开发效率。说得一点都没错,现在写CSS也可以这么爽了。小伙伴们看到这里,必须大吃一惊:“我out了!”

CSS预处理器,这个术语真专业……不过坑爹的术语,往往都是吓唬人的,实际并不难。CSS预处理器,说白了就是用编程方式来写CSS的一类语言,就这么简单。

CSS预处理器语言有很多,最常见的有3种:

  • (1)Sass;
  • (2)Less;
  • (3)Stylus;

这些CSS预处理语言都具备编程的特性,这种编程方式相对于纯CSS书写方式来说,具有更加简洁、适应性更强、可读性更佳、更易于代码的维护等优点。

二、什么是Sass?

Sass是功能最为强大、最成熟、并且是最为流行的CSS预处理器。因此,对于Sass、Less和Stylus这3个,我们还是建议大家学习Sass。

Sass是一种动态样式语言,比CSS多出好些功能(如变量、嵌套、运算、混入、继承、颜色处理、函数等),更容易阅读。

在学习Sass之前,我们需要一定的HTML、CSS和JavaScript基础,以下是先修课程:

(1)HTML入门教程

(2)CSS入门教程

(3)JavaScript入门教程

想要深入学习Sass的小伙伴,也可以到Sass官网看看:Sass官方文档。

三、Sass和Less

Sass和Less是当下最为流行的2门CSS预处理语言,也是国内外讨论最热的2个。很多小伙伴在刚刚接触的时候,总是纠结学哪一门好点。这一节,我们来给大家介绍一下Sass和Less的区别。

Sass和Less差别不大,语法也相近。不管是Sass,还是Less,都可以视为一种基于CSS之上的高级语言,其目的都是为了让CSS开发更为灵活和更强大。但是两者也有以下明显区别:

  • (1)Sass由于是使用Ruby编写的,所以编译的时候是在服务器端处理;而Less由于是使用JavaScript编写的,所以编译的时候是在浏览器端处理;
  • (2)Sass拥有更为强大的功能,如循环、函数、混合宏等,而less却没有;
  • (3)Sass拥有成熟稳定的框架来辅助开发,特别是Compass,而less却没有;
  • (4)Sass在国内外讨论热度最大,并且有一个稳定强大的团队在维护;
  • (5)相当多的公司更为倾向于使用Sass,而不是less;

简单来说,Sass是比less更为强大并且使用更广的一门CSS预处理器语言。在实际开发中,如果你只是单纯地想简化CSS写法、统一风格、增强维护性的话,那么Sass和Less是一样的,学习哪一个都可以。

但是如果想要用到更多并且更加强大的功能的话,那么你应该选择Sass。在这里,我也强烈建议小伙伴们学习的是Sass,而不是Less。Sass最强大之处是配合Compass来辅助CSS开发。其中,Compass是在Sass的一个框架,保证让你爽到爆。对于Compass,别忘了关注即将上线的Compass教程。

四、Sass和Scss

在Sass中,有2种语法格式:(1)Sass格式;(2)Scss格式。也就是说,平常我们所说的Sass和Scss其实是同一个东西来的,统称为Sass。Sass和Scss仅仅是Sass的两种语法格式罢了。

Sass格式

Sass格式,是Sass的“旧版本语法”。这种语法格式,不使用大括号“{}”和分号“;”,而是使用严格的缩进式语法规则来书写,也就是类似Ruby语言的写法。

举例:

$color:white
$bgColor:red
 
body
color:$color
background-color:$bgColor

从这里我们可以看出,Sass格式是不使用大括号“{}”和分号“;”的,并且在body元素定义样式的时候,color和background-color这2个属性都是严格缩进的。说明:

Scss格式

Scss格式,是Sass的“新版本语法”。这种语法格式,使用大括号“{}”和分号“;”,并不使用严格的缩进式语法规则来书写,也就是类似CSS书写的格式。

举例:

$color:white
$bgColor:red
 
body
{ 
    color:$color
    background-color:$bgColor
}

从这里我们可以看出,Scss格式跟平常我们写CSS的格式是一样的。

变量

在JavaScript中,声明变量都是用var。但是在Sass中,我们声明变量使用的是“$”(美元符号)开头。

语法:

sass预处理中文教程(2023开学版)_第8张图片

说明:

我们可以看出,Sass的变量包括3部分:声明符、变量名、值。Sass变量定义的方式,跟CSS语法很相似,这个我们很容易理解。此外我们需要注意一下,定义一个Sass变量必须用“$”开头,不然编译的时候是无法识别的。

在Sass中,对于变量的取值有2种方式:(1)一般值;(2)默认值。

1、一般值

在Sass中,变量的一般值,指的是我们常见的变量值,这个值可以是数字、字符串等。

举例1:

$width:10px;
div
{
    font-size:$width;
}

编译出来的CSS代码如下:

div
{
    font-size:10px;
}

举例2:

$color:white;
$bgColor:red;
body
{
    color:$color;
    background-color:$bgColor;
}

编译出来的CSS代码如下:

body
{
    color:white;
    background-color:red;
}

2、默认值

在Sass中,变量还有一种取值方式,那就是默认值。所谓的默认值,指的是给变量初始化一个默认值,这个值在后面可以根据开发的需要,使用一个“同名变量”的值覆盖掉。定义变量的默认值很简单,我们只需要在“变量值”后面加上“!default”就可以了。

举例:

$width:10px !default;
.div1
{
    width:$width;
}
.div2
{
    $width:20px;
    width:$width;
}
.div3
{
    $width:30px;
    width:$width;
}

编译出来的CSS代码如下:

.div1
{
    width:10px;
}
.div2
{
    width:20px;
}
.div3
{
    width:30px;
}

分析:

想要覆盖变量的默认值很简单,我们只需要在该变量被调用之前重新定义该变量的值就可以了。变量的默认值,在实际开发特别是组件化开发中是非常有用的。当然,这里我们只需要简单了解一下即可。

二、变量的作用域

跟JavaScript的变量一样,Sass的变量也有作用域。在Sass中,变量根据作用域可以分为2种:(1)全局变量;(2)局部变量。

其中,Sass中的作用域跟JavaScript中的作用域是非常相似的。

1、全局变量

在Sass中,全局变量一般指的是在“选择器、混合宏、继承等”外部定义的变量。全局变量从定义开始,一直到整个程序结束都起作用。对于混合宏、继承这些,我们在后续章节会详细介绍。

举例:

$color:red;        //定义全局变量
body
{
    color:$color;  //调用全局变量
}

编译出来的CSS代码如下:

body
{
    color:red;
}

2、局部变量

在Sass中,局部变量一般指的是在“选择器、混合宏、继承等”内部定义的变量。局部变量只能在这些的内部起作用,在这些的外部是不起作用的。

举例:

$color:red;             //定义全局变量
body
{
    $color:green;       //定义局部变量
    div
    {
        color:$color;   //调用局部变量
    }
}

编译出来的CSS代码如下:

body
{
    color:green;
}

分析:

在这个例子中,局部变量“$color:green;”会把全局变量“$color:red;”的值覆盖,因此最终$color的值是green。对于这个,我们联系一下JavaScript中的局部变量和全局变量就不难理解了。

 数据类型

跟JavaScript一样,Sass也有属于自己的数据类型。在Sass中,共有7种数据类型:

  • (1)数字值;
  • (2)字符串;
  • (3)布尔值;
  • (4)颜色值;
  • (5)列表值;
  • (6)Map值;
  • (7)空值null;

接下来,我们在这一节详细介绍一下Sass种的7种数据类型。

一、数字值

在Sass中,数字(Number)是最基本的数据类型,可以是正数、0或负数。数字在Sass中使用非常广泛,大多数都是结合CSS单位来实现的,例如10px、10em或者10%。虽然它们带有单位,但是技术上依然算是数字。

举例:

$lineHeight:1.5;
$fontSize:14px;
$width:50%;
div
{
    lineHeight:$lineHeight;
    font-size:$fontSize;
    width:$width;
}

编译出来的CSS代码如下:

div
{
    line-height:1.5;
    font-size:14px;
    width:50%;
}

二、字符串

在JavaScript中,使用单引号('')或双引号("")包含的都是字符串,就算它们包含的是一个空格,那也是字符串。但是Sass中的字符串跟JavaScript中的字符串有点不一样。

在Sass中,共有2种字符串:

  • (1)有引号的字符串;
  • (2)无引号的字符串;

无引号字符串,我们在CSS中是经常遇到的,例如“font-weight:bold”中的bold、“font-family:sans-serif;”中的sans-serif等。Sass引入无引号字符串的目的也是为了与CSS语法一致。

举例:有引号字符串

$logoUrl: "images/logo.png";
$cursorUrl: "images/default.cur";
$text:"绿叶学习网";
div
{
    background-image:url($logoUrl);
    cursor:url($cursorUrl),default;
}
div:before
{
    content:$text;
}

编译出来的CSS代码如下:

div
{
    background-image:url("images/logo.png");
    cursor:url("images/default.cur"),default;
}
div:before
{
    content:"绿叶学习网";
}

举例:无引号字符串

$str1:sans-serif;
$str2:bold;
div
{
    font-family:$str1;
    font-weight:$str2;
}

编译出来的CSS代码如下:

div 
{
    font-family: sans-serif;
    font-weight: bold;
}

三、布尔值

数字值和字符串这2种数据类型的取值有无数种,但是Sass中的布尔值只有2种取值:true和false。

在Sass中,布尔值一般用于“@if…@esle…语句”条件判断,只有条件表达式结果是false或null才会返回false,其他一切将返回true。

举例:无引号字符串

$a:10px;
$b:5px;
div
{
    @if($a>$b)
    {
        display:block;
    }
    @else
    {
        display:none;
    }
}

编译出来的CSS代码如下:

div
{
    display:block;
}

分析:

Sass中的“@if...@else...”跟JavaScript中的“if...else...”是一样的,这个语句我们在后面“Sass @if语句”这一节中会详细介绍。

在这个例子中,($a>$b)返回的是true,所以div的display属性最终取值为block。

四、颜色值

在Sass,有一种特殊的数据类型,那就是“颜色值”。Sass中的颜色值共有4种:

  • (1)关键字颜色值,如red;
  • (2)十六进制颜色值,如#FFFF00;
  • (3)RGB颜色值,如rgb(255,255,0);
  • (4)HSL颜色值,如;hsl(360,50%,50%);

这几种颜色值都是可以互相转换的,在Sass的颜色运算中,我们都是统一转换为十六进制颜色值然后再计算。对于“Sass颜色运算”,我们在后面章节会详细介绍。

举例:

$fontColor:#FF00FF;
$bgColor:blue;
div
{
    color:$fontColor;
    background-color:$bgColor;
}

编译出来的CSS代码如下:

div
{
    color: red;
    background-color: #FF00FF;
}

五、列表值

在Sass中,为我们提供了一种“列表值”的数据类型,这种数据类型跟JavaScript中的数组是相似的,我们可以把它比作“Sass中的数组”。

Sass列表值有2种语法格式,一种是由英文逗号隔开的分隔值,另外一种是由空格隔开的分隔值。

语法:

$列表名: 值1 , 值2 , ... , 值n;
$列表名: 值1  值2  ... 值n;

说明:

在Sass中,列表值可以包含0个、1个或多个值,甚至还可以包含多个“子列表值”。Sass中的列表值,往往都是用来处理CSS中类似于以下的属性取值:

margin:10px 20px 30px 40px;
padding:10px 20px 30px 40px;
font-family:Microsoft YaHei,Arial,Helvetica,sans-serif;

举例:

$font: Arial,Helvetica,sans-serif;
$margin:20px 40px;
$border:1px solid gray;
div
{
    font:$font;
    margin:$margin;
    border:$border;
}

编译出来的CSS代码如下:

div 
{
    font: Arial, Helvetica, sans-serif;
    margin: 20px 40px;
    border: 1px solid gray;
}

分析:

对于列表值,Sass为我们提供了很多内置的函数,在后面“Sass列表函数”这一章我们会详细介绍。这里我们只需要简单认识一下就可以了。

六、Map值

在Sass中,还为我们提供了另外一种特殊数据类型:Map值。Map值跟JSON值是非常相似的,数据都是以“键/值”的方式成对出现。

语法:

$变量名:
(
    键名1:值1,
    键名2:值2,
    ……
    键名n:值n
);

说明:

Map值的语法结构都是以“(”开始,到“)”结束的。其中“键名”和“值”之间用英文冒号构成对,两个“键名:值”之间用英文逗号分隔。此外还要注意一下,最后一对“键/值”后面是不需要逗号的。

举例:

$theme-color: 
(
    default: 
    (
        bgcolor: #fff,
        text-color: #444,
        link-color: #39f
    ),
    primary:
    (
        bgcolor: #000,
        text-color:#fff,
        link-color: #93f
    ),
    negative: 
    (
        bgcolor: #f36,
        text-color: #fefefe,
        link-color: #d4e
    )
);

分析:

对于Map值,Sass为我们提供了很多内置的函数,在后面“Sass Map函数”这一章我们会详细介绍。这里小伙伴们不需要深入了解Map值,只需要简单认识一下就可以了。

嵌套

Sass为我们提供了一种方便的操作方式:嵌套。在Sass中,共有3种嵌套方式:

  • (1)选择器嵌套;
  • (2)属性嵌套;
  • (3)伪类嵌套;

一、选择器嵌套

选择器嵌套,是Sass中最常见的嵌套方式,这个类似于HTML元素的嵌套。这种嵌套方式我们在之前的章节接触过好几次了,现在再来看一个复杂点的例子。

举例:

$color1:red;
$color2:green;
$color3:blue;
body
{
    color:$color1;
    .column
    {
        color:$color2;
        .content-title
        {
            color:$color3;
        }
    }
}

编译出来的CSS代码如下:

body 
{
  color: red;
}
body .column 
{
  color: green;
}
body .column .content-title
{
  color: blue;
}

分析:

选择器嵌套这种方式虽然操作起来很方便,但是却有一个很大的弊端:嵌套的层级越深,编译出来的CSS代码的选择器层级也越深。这种嵌套方式会导致CSS样式冗余,并且难以维护。

在CSS中,选择器的层级越多,浏览器解析时匹配的次数就越多,因而速度就越慢。因此在定义选择器的时候,我们要尽量让选择器的层级少一些,最好不要超过3层。所以在实际开发中,我们应该尽量注意一下Sass选择器嵌套中的层级问题,尽量少用选择器嵌套的方式来书写Sass。

二、属性嵌套

在Sass中,还为我们提供了一种属性嵌套的方式。我们都知道,CSS有些属性的前缀是相同的,例如:

  • (1)border-top、border-right、border-bottom、border-left这4个属性拥有相同的前缀“border”;
  • (2)margin-top、margin-right、margin-bottom、margin-left这4个属性拥有相同的前缀“margin”;
  • (3)font-family、font-size、font-weight、font-variant等属性拥有相同的前缀“font”;
  • ……

对于这些拥有相同前缀的属性,我们可以使用属性嵌套的方式来简化操作。

举例:

div
{
    width:100px;
    height:100px;
    font:
    {
        family:Arial;
        size:14px;
        weight:bold;
    }
}

编译出来的CSS代码如下:

div 
{
    width: 100px;
    height: 100px;
    font-family: Arial;
    font-size: 14px;
    font-weight: bold;
}

分析:

对于属性嵌套,我们要特别注意一点:在需要嵌套的属性前缀后面一定要加英文冒号“:”,不然编译出来的就不是我们想要的效果。

在上面例子中,如果我们把font后面的冒号去掉,编译出来的CSS代码如下:

div 
{
    width: 100px;
    height: 100px;
}
div font 
{
    family: Arial;
    size: 14px;
    weight: bold;
}

这就完全不是我们预期的效果了。刚刚接触Sass的小伙伴们一定要特别留意这一点。

举例:

div
{
    border:
    {
        top:1px solid red;
        bottom:1px solid green;
    }
}

编译出来的CSS代码如下:

div 
{
    border-top: 1px solid red;
    border-bottom: 1px solid green;
}

三、伪类嵌套或伪元素嵌套

在Sass中,还有一种嵌套方式:伪类嵌套或伪元素嵌套。伪类嵌套(或伪元素嵌套)跟属性嵌套很像,只不过它是需要借助“&”符号一起配合使用。

对于伪类,我们在“CSS入门教程”中的 “CSS超链接伪类”接触过了。CSS3也增加很多伪类,如:first-child、nth-child()等。

伪元素跟伪类是不一样的,常见的伪元素只有4个,即::before、::after、::first-letter、::first-line。对于伪元素和伪类的区别,具体请参考“CSS3教程”进阶部分(即将上线)。

举例:伪类嵌套

$color1:red;  
$color2:green;
a{  
    color:$color1; 
    &:hover
    {  
        color:$color2;
    }
}

编译出来的CSS代码如下:

a
{
    color: red;
}
a:hover 
{
    color: green;
}

分析:

伪类嵌套都是结合“&”符号来实现的,编译的时候“&”会替换成相应的选择器。

举例:伪元素嵌套

.clearfix
{
    *zoom:1;
    &:after
    {
        clear:both;
        content:"";
        display:block;
        height:0;
        visibility:hidden;
    }
}

编译出来的CSS代码如下:

.clearfix{*zoom:1;}
.clearfix::after
{
    clear:both;
    content:"";
    display:block;
    height:0;
    visibility:hidden;
}

分析:

伪元素嵌套同样也是结合“&”符号来实现的,编译的时候“&”会替换成相应的选择器。上面这个是清除浮动最常用的方法,具体原理可以参css float浮动

 Sass插值实例讲解

在Sass中,我们可以通过使用插值的方式来实现在“选择器名”、“属性名”以及“属性值”中插入一个“变量的值”,从而来“构造”一个新的选择器名、新的属性名以及新的属性值。

语法:

#{变量}

说明:

插值这种方式,在Sass代码的几乎任何一个地方都可以插入一个值,包括选择器名、属性名、属性值等。我们还是来个例子比较直观一点。

举例1:插值用于“选择器名”

@for $i from 1 through 3
{
    .item-#{$i}
    {
        width:10px * $i;
    }
}

编译出来的CSS代码如下:

.item-1
{
    width: 10px;
}
.item-2
{
    width: 20px;
}
.item-3
{
    width: 30px;
}

分析:

“@for $i from 1 through 3”很好理解,这表示一个从1到3的循环,在后面“Sass @for循环”这一节我们会详细介绍。

细心的小伙伴们可能就有疑问了,我直接用下面这种插入变量的方式,不也能实现吗?

@for $i from 1 through 3
{
    .item-$i
    {
        width:10px * $i;
    }
}

不好意思,还真不能!变量,我们一般都是用于属性值的,是不能直接用于选择器名中的,不然Sass会无法编译成CSS。

举例:插值用于“属性名”

$border:border;
div
{
    #{$border}-width:1px;
    #{$border}-style:solid;
    #{$border}-color:red;
}

编译出来的CSS代码如下:

div 
{
    border-width: 1px;
    border-style: solid;
    border-color: red;
}

分析:

由于变量只能用于属性值,是不能直接用于属性名的,也就是说如果我们使用下面这种方式是达不到预期效果的:

$border:border;
div
{
    $border-width:1px;
    $border-style:solid;
    $border-color:red;
}

举例:插值用于“属性值”

@for $i from 1 through 3
{
    .item-#{$i}
    {
        border:#{$i}px solid red;
    }
}

编译出来的CSS代码如下:

.item-1
{
    border: 1px solid red;
}
.item-2
{
    border: 2px solid red;
}
.item-3
{
    border: 3px solid red;
}

分析:

在这个例子中,如果我们用以下方式,也是达不到我们预期效果的:

@for $i from 1 through 3
{
    .item-#{$i}
    {
        border:$ipx solid red;
    }
}

这是因为border属性的属性值是一个列表值,而不是单纯的一个数字或字符串。也就是说,如果属性值是一个简单数字或者字符串,我们可以使用变量的方式来实现。但如果属性值是一个复杂的数据类型,我们就必须使用插值的方式来实现。

总而言之,如果你想要在Sass中构造一个新的选择器名、新的属性名以及新的属性值,首先考虑的应该是使用“插值#{}”来实现。

 实现Sass注释的三种方式

一、//注释内容

在Sass中,这种注释方式在编译后不会保留下来。

举例:

$height:20px;
body
{
    //height和line-height值相等,实现单行文字垂直居中
    height:$height;
    line-height:$height;
}

编译出来的CSS代码如下:

body 
{
    height: 20px;
    line-height: 20px;
}

二、/*注释内容*/

在Sass中,这种注释方式在编译之后会保留下来。因为这种注释方式跟CSS注释方式是相同的,所以编译后会保留下来。

举例:

$height:20px;
body
{
    /*height和line-height值相等,实现单行文字垂直居中*/
    height:$height;
    line-height:$height;
}

编译出来的CSS代码如下:

body 
{
    /*height和line-height值相等,实现单行文字垂直居中*/
    height: 20px;
    line-height: 20px;
}

分析:

我们可以看出,在Sass中使用“/*注释内容*/”这种方式,编译出来的CSS也会保留其注释。

三、/*!注释内容*/

我们都知道压缩工具会删除所有的注释,有些时候为了保留一些版权声明的注释说明,可以采用以下方式:

/*!注释内容*/

也就是说在注释内容前面加上一个“!”,这种压缩工具就不会删除这条注释信息了。不过这种注释方式用得很少,一般在CSS文件顶部为了声明版权信息才会使用。

举例:

/*!Copyright ©2015-2017 www.lvyestudy.com, All Rights Reserved*/
$height:20px;
body
{
    height:$height;
    line-height:$height;
}

编译出来的CSS代码如下:

/*!Copyright ©2015-2017 www.lvyestudy.com, All Rights Reserved*/
body 
{
    height: 20px;
    line-height: 20px;
}

sass基本运算

我们都知道,在CSS中能做运算的,也只有cal()函数这一个。不过Sass是一门“编程”式的语言,它为我们提供了类似于JavaScript的各种运算方式,例如加、减、乘、除等。

在Sass中,共有3种运算情况:

  • (1)数字运算;
  • (2)字符运算;
  • (3)颜色运算;

接下来,我们一一给大家详细介绍。

第一种数字运算

在Sass中,共有4种数字运算:

  • (1)加法;
  • (2)减法;
  • (3)乘法;
  • (4)除法;

这4种运算方式,我们在其他编程语言(如JavaScript)也能看到,但是Sass的这4种运算不太一样,还是有不少我们需要注意的地方。所以在这一节中,小伙伴们要细心留意一下。

一、Sass加法

在Sass中,做加法运算时,数值可以带单位,但是需要运算单位相同。如果不相同就会报错,编译不通过。

举例1:运算单位相同

div
{
    width:(100px + 20px);
}

编译出来的CSS代码如下:

div
{
    width:120px;
}

分析:

由于“100px”和“20px”的单位相同,都是px。所以在Sass中,这两个可以做加法运算。

举例2:运算单位不同

div
{
    width:(100px + 20em);
}

编译出来的CSS代码如下:

Incompatible units: 'em' and 'px'.

分析:

因为“100px”和“20em”单位不同,所以在Sass编译的时候会报错。其中,“Incompatible units: 'em' and 'px'.”意思是“em和px单位不一致”。

我们再来看一个实际开发中的例子,体会一下Sass加法的用法:

$sidebar-width:220px;
$content-width:720px;
$gap-width:20px;
.container
{
    width: ($sidebar-width + $content-width + $gap-width)
    margin: 0 auto;
}

编译出来的CSS代码如下:

.container
{
    width:960px;
    margin:0 auto;
}

二、Sass减法

在Sass中,做减法运算时,数值可以带单位,但是需要运算单位相同。如果不相同就会报错,编译不通过。这一点跟Sass加法是一样的。

举例1:运算单位相同

div
{
    width:(100px - 20px);
}

编译出来的CSS代码如下:

div
{
    width:80px;
}

分析:

由于“100px”和“20px”的单位相同,都是px。所以在Sass中,这两个可以做减法运算。

举例2:运算单位不同

div
{
    width:(100px - 20em);
}

编译出来的CSS代码如下:

Incompatible units: 'em' and 'px'.

分析:

因为“100px”和“20em”单位不同,所以在Sass编译的时候会报错。其中,“Incompatible units: 'em' and 'px'.”意思是“em和px单位不一致”。

我们也来看一个实际开发中的例子,体会一下Sass减法的用法:

$container-width:960px;
$sidebar-width:200px;
.content
{
    width: ($container-width - $sidebar-width);
}

编译出来的CSS代码如下:

.content
{
    width:760px;
}

分析:

在Sass中,如果是做减法运算是“变量”而不是“数值”的时候,我们要注意减号“-”前后一定要有空格。像上面这个例子,如果减号前后没有空格:

$container-width:960px;
$sidebar-width:200px;
.content
{
    width: ($container-width-$sidebar-width);
}

像上面这样,Sass是无法正确地识别哪个“-”是变量的一部分,哪个“-”是减号。不过对于Sass中的加法,则不需要考虑这一点。

三、Sass乘法

在Sass中,做乘法运算时,只能有一个数值带单位,另外一个数值只能是不带单位的数字。如果两个都是带单位的数字,则Sass会报错而编译不通过。其实,小伙伴们稍微想一下平常数学中的运算,就很容易明白。

举例1:一个带单位,另外一个不带单位

div
{
    width:(100px * 2);
}

编译出来的CSS代码如下:

div
{
    width:200px;
}

举例2:两个都带单位

div
{
    width:(100px * 2px);
}

编译出来的CSS代码如下:

200px*px isn't a valid CSS value.

分析:

“200px*px isn't a valid CSS value.”意思是:200px*px不是一个有效的CSS属性值。我们再来看一个实际开发中的例子,体会一下Sass乘法的用法:

@for $i from 1 through 3
{
    .item-#{$i}
    {
        width:10px * $i;
    }
}

编译出来的CSS代码如下:

.item-1
{
    width: 10px;
}
.item-2
{
    width: 20px;
}
.item-3
{
    width: 30px;
}

四、Sass除法

我们都知道,“/”在CSS中已经作为一种符号来使用了,例如我们常见的字体属性缩写“font:Arial 12px/1.5em”。因此在Sass中做除法运算的时候,如果我们直接使用“/”符号作为除号,将不会生效。

在Sass中,如果我们想要做除法运算,我们需要在外面添加一个“小括号()”。

举例:

div
{
    width:(100px/2);
}

编译出来的CSS代码如下:

div
{
    width:50px;
}

分析:

在这个例子中,如果我们将小括号去掉,则Sass编译的时候会报错。但是在Sass中,如果做除法运算中是“变量”而不是“数值”时,“/”会被自动识别为除法,不需要在外面添加小括号。

举例:

$width:100px;
div
{
    width:$width/2;
}

编译出来的CSS代码如下:

div
{
    width:50px;
}

在使用Sass的过程中,“/”这个符号被当做除法运算时有以下3种情况:

  • (1)数值被小括号()包含;
  • (2)数值是另外一个数学表达式的一部分;
  • (3)数值或它的任意部分存储在一个变量中或者函数的返回值;

举例:

$height:100px;
div
{
    font:20px/10px;                 //纯CSS,不是除法运算
    width:(20px/10px);              //使用了小括号,是除法运算,符合第1点
    height:$height/2;               //使用了变量,是除法运算,符合第3点
    line-height:round(1.5)/2;       //使用了函数,是除法运算,符合第3点
    margin-left:10px + 10px/2px;    //使用了加号,是除法运算,符合第2点
}

编译出来的CSS代码如下:

div 
{
    font: 20px/10px;
    width: 2;
    height: 50px;
    line-height: 1;
    margin-left: 15px;
}

分析:

在实际开发中,不管是加法、减法,还是乘法、除法运算,我们都建议在外面加上小括号。这种书写方式,能够使得代码一目了然,也方便维护。希望小伙伴们也规范一下自己的书写方式。

 字符运算

在之前“Sass数据类型”这一节我们知道,CSS有2种字符串类型:(1)有引号字符串;(2)无引号字符串。

在Sass中,我们可以使用“+”(加号)来实现字符串的拼接。对于字符串的连接,我们分为3种情况来考虑:

  • (1)如果左右两个字符串都是有引号的,结果是一个有引号的字符串;
  • (2)如果左边字符串是有引号的,右边字符串是没有引号的,结果是一个有引号的字符串;
  • (3)如果左边字符串是没有引号的,右边字符串是有引号的,结果是一个没有引号的字符串;

一句话概括:结果字符串是否有引号,取决于左边字符串是否有引号。

举例:

div::before
{
    content: "Welcome to " + lvyestudy;
    font:sans- + "serif";
}

编译出来的CSS代码如下:

div:before 
{
    content: "Welcome to lvyestudy";
    font: sans-serif;
}

分析:

Sass之所以会引入2种字符串,也是为了与CSS的语法一致。

颜色运算

颜色值是Sass中的一种特殊的数据类型,我们在之前“Sass数据类型”这一节已经详细介绍过了。

在Sass中,我们也是可以对颜色值进行运算的。颜色运算支持加、减、乘、除,并且是分段进行计算的。也就是说,红、绿、蓝这3个部分的颜色是单独进行计算的。

举例1:

div
{
    color: (#010203 + #040506);
}

编译出来的CSS代码如下:

div
{
    color: #050709;
}

分析:

由于颜色运算是分段的,其中红、绿、蓝3个部分单独进行计算,所以这个例子的计算方式为:

01 + 04=05,
02 + 05=07,
03 + 06=09

最后,将这3段计算后的结果合并得到最终颜色值:#050709。

举例2:

div
{
    color: (#010203 * 2);
}

编译出来的CSS代码如下:

div
{
    color: #020406;
}

分析:

由于颜色运算是分段的,其中红、绿、蓝3个部分单独进行计算,所以这个例子的计算方式为:

01 * 2=02,
02 * 2=04,
03 * 2=06

最后,将这3段计算后的结果合并得到最终颜色值:#020406。

此外,如果颜色值不是十六进制颜色值(如#010203),而是RGB或者HSL的话,我们都是将RGB或HSL先转换为十六进制颜色值,然后再进行加、减、乘、除运算的。

div
{
    color:(rgb(17,34,51) *2);
}

编译出来的CSS代码如下:

div 
{
    color: #224466;
}

分析:rgb(17,34,51转化为十六进制颜色值为“#112233”,然后进行乘法运算,最后得到最终颜色值:#224466。

Sass代码重用

在实际开发中,我们经常会碰到好些不同地方都用到相同的CSS样式的情况。如果相同的CSS样式只有一个CSS属性,此时只需要使用Sass变量实现就可以满足了。如果相同的CSS样式有多个CSS属性,这个时候我们就希望把“相同的CSS样式”当做整块来处理。

在Sass中,为我们提供了3种方式来处理经常被多个地方使用的相同的CSS代码块:

  • (1)继承“@extend”;
  • (2)占位符“%placeholder”;
  • (3)混合宏“@mixin”;

这几种实现代码重用的方式,在Sass开发中非常非常重要,因为使用这些可以极大地提高我们的开发效率,所以这一章小伙伴们要重点学习。接下来我们一一给大家详细介绍。

 Sass继承实例讲解

CSS具有2大特性:继承性和层叠性。CSS的继承性,指的是子元素继承了父元素的某些样式属性,例如在父元素中定义字体颜色(color),子元素会继承父元素的字体颜色。

在Sass中,我们可以使用“@extend”来继承一个样式块,从而实现代码的重用。

举例1:

.spriteAll
{
    bakckground:url(images/sprite.png) no-repeat;
}
.sprite-1
{
    @extend .spriteAll;
    background-position:0 -30px;
}
.sprite-2
{
    @extend .spriteAll;
    background-position:0 -60px;
}

编译出来的CSS代码如下:

.spriteAll, .sprite-1, .sprite-2
{
    bakckground: url(images/sprite.png) no-repeat;
}
.sprite-1
{
    background-position: 0 -30px;
}
.sprite-2
{
    background-position: 0 -60px;
}

分析:

在这个例子中,我们定义了一个“.spriteAll”类用来存放公共样式,然后在“.sprite-1”和“.sprite-2”中使用@extend来继承“.spriteAll”类。

举例:

.btn
{
    padding:6px 10px;
    border:1px solid silver;
    font-size:14px;
}
.btn-primary
{
    @extend .btn;
    color:white;
    background-color:red;
}
.btn-second
{
    @extend .btn;
    color:orange;
    background-color:green;
}

编译出来的CSS代码如下:

.btn, .btn-primary, .btn-second
{
    padding: 6px 10px;
    border: 1px solid silver;
    font-size: 14px;
}
.btn-primary 
{
    color: white;
    background-color: red;
}
.btn-second 
{
    color: orange;
    background-color: green;
}

分析:

在这个例子中,我们定义了一个“.btn”类用来存放公共样式,然后在“.btn-primary”和“.btn-second”中使用@extend来继承“.btn”类。

从上面两个例子我们可以看出,继承这种方式来实现代码的重用是非常实用的。它使得代码更为精简,并且一目了然,具有更高的可读性和可维护性。

Sass占位符实例讲解

在Sass中,我们引入了占位符“%placeholder”来进一步优化“@extend”。我们先来看一个例子。

举例:使用继承“@extend”

.btn
{
    padding:6px 10px;
    border:1px solid silver;
    font-size:14px;
}
.btn-primary
{
    @extend .btn;
    color:white;
    background-color:red;
}
.btn-second
{
    @extend .btn;
    color:orange;
    background-color:green;
}

编译出来的CSS代码如下:

.btn, .btn-primary, .btn-second
{
    padding: 6px 10px;
    border: 1px solid silver;
    font-size: 14px;
}
.btn-primary 
{
    color: white;
    background-color: red;
}
.btn-second 
{
    color: orange;
    background-color: green;
}

分析:

从这个例子我们可以看出,继承“@extend”是非常好用的。通过@extend,我们可以直接在“.btn-primary”和“.btn-second”中插入定义好的“.btn”,这样每次只要你修改了“.btn”中的样式,“.btn-primary”和“.btn-second”中的样式都会同时修改。

但是稍微细心的小伙伴应该也发现了,如果我们的HTML中没有任何一个元素使用“.btn”的话,“.btn”存在的唯一目的就是仅仅用来给“.btn-primary”和“.btn-second”继承。也就是说,“.btn”这个类在编译出来的CSS中是多余的。那有没有更好的办法来实现我们预期效果呢?

在新版本的Sass中,引入了“占位符%placeholder”来优化“继承@extend”的输出。

举例:

%btn
{
    padding:6px 10px;
    border:1px solid silver;
    font-size:14px;
}
.btn-primary
{
    @extend %btn;
    color:white;
    background-color:red;
}
.btn-second
{
    @extend %btn;
    color:orange;
    background-color:green;
}

编译出来的CSS代码如下:

.btn-primary, .btn-second
{
    padding: 6px 10px;
    border: 1px solid silver;
    font-size: 14px;
}
.btn-primary 
{
    color: white;
    background-color: red;
}
.btn-second 
{
    color: orange;
    background-color: green;
}

分析:

上一个例子,我们是定义一个基类“.btn”(类,都是以“.”开头)。而在这个例子中,我们是定义一个占位符“%btn”(占位符,都是以“%”开头)。我们对比一下这两个例子的输出结果就可以知道,使用占位符的输出结果是不包含基类的。

“占位符%placeholder”并非用来替换“继承@extend”的,而是用来配合“继承@extend”来使用的。从上面我们可以知道,继承@extend有2种输出方式:

  • (1)需要保留基类的:只使用@extend来实现;
  • (2)不需要保留基类的:使用@extend配合%placeholder来实现;

此外在实际开发中,继承中的基类是否就一定要去掉呢?这个倒不一定。如果你的HTML结构需要用到基类,则不需要使用占位符的方式来去掉;如果你的HTML不需要用到基类,则建议使用占位符配合继承来去掉。

Sass混合宏实例介绍

在Sass中,我们可以使用“混合宏(mixin)”来处理经常被多个地方使用的相同的CSS代码块。混合宏,跟JavaScript中的函数很相似,我们可以称之为“Sass中的函数”。

一、混合宏的定义和调用

在Sass中,我们使用“@mixin”来定义一个混合宏,然后使用“@include”来调用一个混合宏。

语法:

//定义一个混合宏
@mixin 混合宏名
{
    样式属性1:取值1;
    样式属性2:取值2;
    ……
}
//调用一个混合宏
选择器
{
    @include 混合宏名;
}

说明:

Sass中的混合宏跟C语言的宏是非常相似的。所谓的“宏”,指的是可重用的代码块。

@mixin用来定义一个混合宏,@include用来调用一个混合宏。此外,@mixin跟CSS3中的@font-face和@media语法是一样的。

举例:

@mixin radius
{
    border-radius:5px;
    -webkit-border-radius:5px;
    -moz-border-radius:5px;
}
#header
{
    color:red;
    @include radius;
}
#footer
{
    color:green;
    @include radius;
}

编译出来的CSS代码如下:

#header
{
    color: red;
    border-radius: 5px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
}
#footer
{
    color: green;
    border-radius: 5px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
}

二、混合宏的参数

在Sass中,我们不仅可以定义“不带参数的混合宏”,也可以定义“带参数的混合宏”。其中,混合宏的参数可以是1个,也可以是N个。

举例:带一个参数的混合宏

@mixin radius($radius)
{
    border-radius:$radius;
    -webkit-border-radius:$radius;
    -moz-border-radius:$radius;
}
#header
{
    color:red;
    @include radius(3px);
}
#footer
{
    color:green;
    @include radius(5px);
}

编译出来的CSS代码如下:

#header
{
    color: red;
    border-radius: 3px;
    -webkit-border-radius: 3px;
    -moz-border-radius: 3px;
}
#footer
{
    color: green;
    border-radius: 5px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
}

举例:带多个参数的混合宏

@mixin center($width,$height)
{
    width: $width;
    height: $height;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-top: -($height) / 2;
    margin-left: -($width) / 2;
}
div
{
    @include center(100px,80px);
}

编译出来的CSS代码如下:

div 
{
    width: 100px;
    height: 80px;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-top: -40px;
    margin-left: -50px;
}

分析:

这个混合宏里面的CSS代码是一个功能代码块,是用来同时实现元素的水平居中和垂直居中的。在实际开发中,对于这些功能代码块,我们都是配合混合宏(mixin)来使用,非常的简单快速。现在大家体会到Sass比纯CSS强大的地方了吧。

在Sass中,我们还可以为混合宏传递的参数定义默认值。混合宏参数的默认值,跟变量的默认值是非常相似的,小伙伴们记得对比一下,这样更能加深理解和记忆。

举例:参数带默认值

@mixin radius($radius:3px)
{
    border-radius:$radius;
    -webkit-border-radius:$radius;
    -moz-border-radius:$radius;
}
#header
{
    color:red;
    @include radius;
}
#footer
{
    color:green;
    @include radius(5px);
}

编译出来的CSS代码如下:

#header
{
    color: red;
    border-radius: 3px;
    -webkit-border-radius: 3px;
    -moz-border-radius: 3px;
}
#footer
{
    color: green;
    border-radius: 5px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
}

分析:

在这个例子中,我们给“混合宏radius”传了一个参数“$radius”,并且给这个参数定义了一个默认值“3px”。如果我们页面有很多地方的圆角都是“3px”的话,那么这种默认值的方式就会非常

 sass流程控制

Sass流程控制@if语句

在Sass中,我们可以使用“@if语句”来进行条件选择判断。Sass的条件选择语句共有3种:

  • (1)@if…(单向选择);
  • (2)@if…@else…(双向选择);
  • (3)@if…@else if…(多向选择);

接下来,我们一一详细介绍这3种条件选择语句。

一、@if语句

在Sass中,我们可以使用“@if…”来实现单向选择。

举例:

div
{
    @if (10px>5px)
    {
        border:1px solid gray;
    }
}

编译出来的CSS代码如下:

div
{
    border:1px solid gray;
}

二、@if…@else…

在Sass中,我们可以使用“@if…@else…”来实现双向选择。

举例:

@mixin checkBlock($boolean:true)
{
    @if $boolean
    {
        display:block;
    }
    @else
    {
        display:none;
    }
}
.block
{
    @include checkBlock;
}
.hidden
{
    @include checkBlock(false);
}

编译出来的CSS代码如下:

.block
{
    display: block;
}
.hidden
{
    display: none;
}

分析:

这里定义了带有一个参数的混合宏checkBlock,参数默认值为true。然后使用“@if…@else…”语句对传过来的参数进行判断,从而决定元素display属性值为block(显示),还是none(隐藏)。

三、@if…@else if…

在Sass中,我们可以使用“@if…@else if…”来实现多向选择。

举例:

@mixin checkColor ($width)
{
    @if ($width>100px)
    {
        color:red;
    }
    @else if ($width<100px)
    {
        color:green;
    }
    @else
    {
        color:blue;
    }
}
div
{
    @include checkColor(100px);
}

编译出来的CSS代码如下:

div
{
    color:blue;
}

分析:

“@if…@else if…”这种多向选择的语句在Sass用得比较少,我们只需要简单了解一下即可。

 @for循环

接触过Boostrap的小伙伴,估计都见过.col1~.col12这样的样式。在CSS中,对于这种样式我们一般都需要一个一个地书写。但是在Sass中,我们可以使用@for循环来实现。

在Sass中,我们可以使用“@for”来实现循环操作。其中,Sass中的@for循环有2种方式。

语法:

方式1:@for $i from 开始值 through 结束值
方式2:@for $i from 开始值 to 结束值

说明:

这2种方式是相似的,唯一的区别是:方式1包括结束值,方式2不包括结束值。其中“开始值”和“结束值”都是正整数。

举例1:

@for $i from 1 through 3
{
    .item-#{$i}
    {
        width:(20px * $i);
    }
}

编译出来的CSS代码如下:

.item-1
{
    width:20px;
}
.item-2
{
    width:40px;
}
.item-3
{
    width:60px;
}

分析:

如果将“@for $i from 1 through 3”改为“@for $i from 1 to 3”,则编译出来的CSS代码如下:

.item-1
{
    width:20px;
}
.item-2
{
    width:40px;
}

举例2:

@for $i from 1 through 3
{
    .border-#{$i}
    {
        border:#{$i}px solid red;
    }
}

编译出来的CSS代码如下:

.border-1
{
    border: 1px solid red;
}
 
.border-2
{
    border: 2px solid red;
}
 
.border-3
{
    border: 3px solid red;
}

分析:

如果小伙伴们忘了“插值#{}”的用法,记得回去翻翻“Sass插值”这一节。

 Sass流程控制@while循环

在Sass中,我们也可以使用@while语句来实现循环操作。跟JavaScript一样,@while语句既是循环语句,也是条件判断语句。

语法:

@while(判断条件)
{
    执行语句;
}

说明:

在Sass中,没有类似于JavaScript的“do...while...”这种语句。这一点小伙伴们要注意一下。

举例1:使用@while循环

$i:3;
@while ($i>0)
{
    .item-#{$i}
    {
        width: (20px + $i);
    }
    $i : ($i - 1);   //递减操作
}

编译出来的CSS代码如下:

.item-3
{
    width: 23px;
}
 
.item-2
{
    width: 22px;
}
 
.item-1
{
    width: 21px;
}

分析:

当然,对于上面这个例子,我们也可以使用for循环来实现,效果是一样的。

举例2:使用@for循环

@for $i from 1 through 3
{
    .item-#{$i}
    {
        width:(20px+$i);
    }
}

编译出来的CSS代码如下:

.item-1
{
    width: 21px;
}
.item-2
{
    width: 22px;
}
.item-3
{
    width: 23px;
}

分析:

细心的小伙伴们可能就会有疑问了:对于“width:(20px+$i);”这个,$i是一个数字,而20px是像素,这可以进行相加吗?其实,在之前“Sass数据类型”这一节已经说过了:在Sass中,带有单位的数值我们也可以把它当做一个“数字”来处理。

此外,我们还要记得一点:带单位的数字与不带单位的数字是可以进行相加,结果是一个带单位的数字。但是带单位的数字与不带单位的数字是不可以相减的,小伙伴们可以自行测试一下。

Sass流程控制@each循环 

除了@for以及@while这2种循环方式之外,Sass还为我们提供了另外一种循环方式:each循环。Sass中的each循环跟jQuery中的each循环很相似,大家对比一下。

语法:

@each $var in 列表值
{
    ……
}

说明:

$var是一个变量,也可以根据后面列表值表示的内容需要写成$item、$color等。列表值,是Sass中的一种数据类型,可以称之为“Sass中的数组”。对于列表值,我们在之前的“Sass数据类型”这一节已经接触过了。

举例:图片循环

$list:logo,banner,btn;
@each $var in $list
{
    .#{$var}-img
    {
        background-image:url("images/#{$var}.png");
    }
}

编译出来的CSS代码如下:

.logo
{
    background-image: url("images/logo.png");
}
.banner
{
    background-image: url("images/banner.png");
}
.btn
{
    background-image: url("images/btn.png");
}

分析:

在这个例子中,我们使用@each循环快速生成背景图片样式。这种技巧在实际开发中也经常被用到。

举例:图片合并

$list:sprite1,sprite2,sprite3;
%spriteAll
{
    background:url("images/sprite.png") no-repeat;
}
@each $var in $list
{
    .#{$var}
    {
        @extend %spriteAll;
        background-position: 0 index($list,$var) * (-30px);
    }
}

编译出来的CSS代码如下:

.sprite1, .sprite2, .sprite3
{
    background: url("images/sprite.png") no-repeat;
}
.sprite1
{
    background-position: 0 -30px;
}
.sprite2
{
    background-position: 0 -60px;
}
.sprite3
{
    background-position: 0 -90px;
}

分析:

从上面这个例子可以看出,我们使用@each循环来操作CSS Sprite图片是非常方便的。CSS Sprite技巧在实际开发中大量用到,具体原理以及使用请参考《css sprite讲解与使用实例》

举例:

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

编译出来的CSS代码如下:

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

你可能感兴趣的:(sass,sass,css,前端)