天天看点

CSS预处理器 Sass/Scss

文章目录

    • 介绍
      • Sass是什么
      • Scss是什么
      • Scss 与 Sass异同
      • 为什么使用 Sass?
    • Sass 安装
      • NPM 安装(推荐使用)
      • Windows 上安装
      • Mac OS X (Homebrew)安装
    • Sass 转化为 CSS
      • 转化步骤
      • 自动编译
    • 编译输出的CSS格式
        • :nested:嵌套(默认格式)
        • :compact:紧凑
        • :expanded:扩展
        • :compressed:压缩
    • Sass 语法
      • 注释
      • 变量`$`
      • 嵌套
        • 1. 选择器嵌套
        • 2. 父选择器 `&`
        • 3. 属性嵌套
      • 插值语句 `#{}`
      • 数据类型
      • 运算
        • 数字运算
        • 颜色值运算
        • 字符串运算
        • 布尔运算
        • 数组运算
      • 混合-Mixins
      • 控制语句
        • @if
        • @for
        • @each
        • @while
      • Partials与@import
        • @import
        • Sass 导入文件
        • 局部文件(Partial)
      • 函数
      • Sass 颜色函数
        • Sass 颜色设置
      • @media
      • 继承(@extend)
      • 警告与错误
    • 了解更多

介绍

Sass是什么

Sass (英文全称:Syntactically Awesome Stylesheets) 是一个最初由 Hampton Catlin 设计并由 Natalie Weizenbaum 开发的层叠样式表语言。Sass 是一个 CSS 预处理器,是 CSS 扩展语言,可以帮助我们减少 CSS 重复的代码,节省开发时间。

Sass 扩展了 CSS3,增加了规则、变量、混入、选择器、继承、内置函数等等特性。

Sass 生成良好格式化的 CSS 代码,易于组织和维护。

Sass 文件后缀为 . s c s s \color{red}{.scss} .scss。

Scss是什么

Scss 是 Sass 3 引入新的语法,是Sassy CSS的简写,是CSS3语法的超集。说白了Scss就是Sass的升级版,其语法完全兼容 CSS3,并且继承了 Sass 的强大功能。也就是说,任何标准的 CSS3 样式表都是具有相同语义的有效的 SCSS 文件。另外,SCSS 还能识别大部分 CSS hacks(一些 CSS 小技巧)和特定于浏览器的语法。

所有在 CSS 中正常工作的代码也能在 Scss 中正常工作。也就是说,对于一个 Sass 用户,只需要理解 Sass 扩展部分如何工作的,就能完全理解 Scss。大部分扩展,例如变量、parent references 和 指令都是一致的;唯一不同的是,SCSS 需 要 使 用 分 号 和 花 括 号 而 不 是 换 行 和 缩 进 \color{red}{需要使用分号和花括号而不是换行和缩进} 需要使用分号和花括号而不是换行和缩进。

Scss 与 Sass异同

Sass 和 Scss 其实就是同一种东西,我们平时都称之为 Sass,两者之间不同之处主要有以下两点:

  1. 文件扩展名不同:Sass 是以

    “.sass”

    后缀为扩展名,而 Scss 是以

    “.scss”

    后缀为扩展名。
  2. 语法书写方式不同:Sass 是以严格的缩进式语法规则来书写,不带大括号({})和分号(😉,而 Scss 的语法书写和我们的CSS 语法书写方式非常类似。

我们不妨来看看下面两段代码,这样会更加直观,更容易理解。

Scss代码

/* 注
   释*/
// 注
// 释
@import "base";
$font-stack:    Helvetica, sans-serif;
$primary-color: #333;

body {
  font: 100% $font-stack;
  color: $primary-color;
}
@mixin alert {
    color: #000000;
}
.alert-warning {
    @include alert;
}
           

Sass代码

/* 注
   释
// 注
   释
@import base
$font-stack:    Helvetica, sans-serif
$primary-color: #333

body
  font: 100% $font-stack
  color: $primary-color
  
=alert 
  color: #000000

.alert-warning 
  +alert

           

编译为:

/* 这里只展示body中的代码 */
body {
  font: 100% Helvetica, sans-serif;
  color: #333;
}
           

为什么使用 Sass?

CSS 本身语法不够强大,导致重复编写一些代码,无法实现复用,而且在代码也不方便维护。

Sass 引入合理的样式复用机制,增加了规则、变量、混入、选择器、继承、内置函数等等特性。

Sass 安装

本章节我们主要介绍 Sass 的安装与使用。

NPM 安装(推荐使用)

我们可以使用 npm(NPM 使用介绍)来安装 Sass。

npm install -g sass
           

**注:**国内 npm 建议使用淘宝镜像来安装

Windows 上安装

我们可以使用 Windows 的包管理器 Chocolatey 来安装:

choco install sass
           

Mac OS X (Homebrew)安装

Mac OS 可以使用 Homebrew 包管理器来安装:

brew install sass/sass/sass
           

官网安装流程:安装Sass | Sass中文网

Sass 转化为 CSS

转化步骤

  1. 首先创建.scss文件及其存放目录和css文件的存放目录
  2. 然后在.scss文件中书写sass代码
  3. 最后cd到.scss文件存放目录,在命令行输入
    sass sass/test1.scss css/test1.css
               
    sass sass/test1.scss:css/test1.css
               
    **注:**sass/test1.scss为sass代码存放目录及文件名;css/test1.css为css代码存放目录及编译完成后css代码存放文件。

逆向操作,css文件转换为sass/scss文件

sass-convert style.css style.sass
sass-convert style.css style.scss
           

自动编译

每次修改sass代码都需要重新执行命令,非常的麻烦,所以下面讲述一种自动实时编译的方式。

监视单个 Sass 文件(每次修改并保存时自动编译)

sass --watch input.scss:output.css
           

例:对当前文件夹下sass/test1.scss监听,并自动编译生成css/test1.css

sass --watch sass/test1.scss:css/test1.css 
           

监视整个文件夹

输入命令:

sass --watch sass文件夹名:css文件夹名  
           

例:

sass --watch sass:css
           

停止监视

在命令行界面按下:Ctrl + C

编译输出的CSS格式

编译输出的CSS格式一共有四种:

  • nested:嵌套(默认格式)
  • compact:紧凑
  • expanded:扩展
  • compressed:压缩

实例:

// sass
ul{
  font-size: 15px;
  li{
    list-style: none;
    line-height: normal;
  }
}
           

:nested:嵌套(默认格式)

在执行监测(编译)命令时,可以指定输出格式为

nested

sass --watch sass:css --style nested
           

输出css格式:

ul {
  font-size: 15px; }
ul li {
  list-style: none;
  line-height: normal; }
           

:compact:紧凑

紧凑格式占用的空间要小得多,每个CSS选择符定义只占用一行。

要将CSS输出设置为紧凑格式,可以使用如下命令:

sass --watch sass:css --style compact
           

输出css格式:

ul { font-size: 15px; }
ul li { list-style: none; line-height: normal; }
           

:expanded:扩展

展开格式看起来像开发人员手写的格式。

要将CSS输出设置为展开格式,可以使用如下命令:

sass --watch sass:css --style expanded
           

输出css格式:

ul {
  font-size: 15px;
}
ul li {
  list-style: none;
  line-height: normal;
}
           

:compressed:压缩

压缩格式占用尽可能少的空间,选择符定义不换行,文件最小,一般用于生产版本。

要将CSS输出设置为压缩格式,可以使用如下命令:

sass --watch sass:css --style compressed
           

输出css格式:

Sass 语法

注释

scss文件中

/* 多行注释 
*  会包含在没有压缩之后的css里面*/
// 单行注释(不会出现在css里面)
           

编译为:

@charset "UTF-8";
/* 多行注释 
*  会包含在没有压缩之后的css里面*/
           

**注:**如果编译输出的CSS格式是

compressed:压缩

时,多行注释也不会再css文件中出现。

如果想要编译输出的CSS格式是

compressed:压缩

时,多行注释仍然在css文件中出现。

scss文件

/* 多行注释 */
/*! 强制输出的注释内容
*/
ul{
  font-size: 15px;
  li{
    list-style: none;
    line-height: normal;
  }
}
           

编译后的css文件

/*! 强制输出的注释内容
*/ul{font-size:15px}ul li{list-style:none;line-height:normal}
           

变量

$

变量以美元符号开头,赋值方法与 CSS 属性的写法一样:

$color:#000000; // 变量声明
$highlight-color: #F90;
$highlight-border: 1px solid $highlight-color; // 将变量直接赋值给border属性
div{ // 变量引用
    color:$color;
    border: $highlight-border;
}
           

编译为:

/* css */
div {
    color: #000000;
    border: 1px solid #F90;
}
           

将局部变量转换为全局变量可以添加

!global

声明:

#main {
  $width: 5em !global;
  width: $width;
}
#sidebar {
  width: $width;
}
           

编译为:

/* css */
#main {
  width: 5em;
}
#sidebar {
  width: 5em;
}
           

嵌套

Sass支持选择器及属性嵌套,可以避免代码的重复书写。

1. 选择器嵌套

div {
    h1 {
        color: #333;
    }
    p {
        margin-bottom: 1.4px;
        a {
            color: #999;
        }
    }
}
           

编译为:

/* css */
div h1 { color: #333; }
div p { margin-bottom: 1.4px; }
div p a { color: #999; }
           

2. 父选择器

&

在嵌套 CSS 规则时,有时也需要直接使用嵌套外层的父选择器,例如,当给某个元素设定

hover

样式时,或者当

body

元素有某个 classname 时,可以用

&

代表嵌套规则外层的父选择器。

a {
    font-weight: bold;
    text-decoration: none;
    &:hover { text-decoration: underline; 
    }
    body.firefox & { font-weight: normal; 
    }
}
           

编译为:

/* css */
a {
    font-weight: bold;
    text-decoration: none; 
}
a:hover {
    text-decoration: underline; 
}
body.firefox a {
    font-weight: normal; 
}
           

3. 属性嵌套

div {
  border: 1px solid #ccc {
  left: 0px;
  right: 0px;
  }
}
           

编译为:

/* css */
div {
  border: 1px solid #ccc;
  border-left: 0px;
  border-right: 0px;
}
           

插值语句

#{}

通过

#{}

插值语句可以在选择器或属性名中使用变量:

$name: foo;
$attr: border;
p.#{$name} {
  #{$attr}-color: blue;
}
           

编译为:

/* css */
p.foo {
  border-color: blue; }
           

数据类型

Sass支持 7 种主要的数据类型:

  • Number 类型(数字类型):

    1, 2, 13, 10px

  • String 类型(字符串类型):有引号字符串与无引号字符串,

    "foo", 'bar', baz

  • Colors类型(颜色类型):

    blue, #04a3f9, rgba(255,0,0,0.5)

  • Boolean 类型(布尔类型):

    true, false

  • 空值(Null):

    null

  • Lists 类型(列表类型):用空格或逗号作分隔符,

    1.5em 1em 0 2em, Helvetica, Arial, sans-serif

  • Maps类型,相当于 JavaScript 的 object,

    (key1: value1, key2: value2)

Sass也支持其他 CSS 属性值,比如 Unicode 字符集,或

!important

声明。然而Sass 不会特殊对待这些属性值,一律视为无引号字符串。

运算

数字运算

Sass支持数字的加减乘除、取整等运算 (

+, -, *, /, %

),如果必要会在不同单位间转换值。

关系运算

<, >, <=, >=

也可用于数字运算,相等运算

==, !=

可用于所有数据类型。

实例:

p {
  width: 1 + 50px;
  height: 50 * 2px;
}
           

编译为:

/* css */
p {
  width: 51px;
  height: 100px;
}
           

除法运算

以下三种情况

/

将被视为除法运算符号:

  • 如果值,或值的一部分,是变量或者函数的返回值
  • 如果值被圆括号包裹
  • 如果值是算数表达式的一部分
p {
  font: 20px/4px;           
  $width: 100px;
  width: $width/2;            
  width: round(2.5)/2;      
  height: (50px/2);          
  margin-left: 4px + 18px/2px; 
}
           

编译为:

/* css */
p {
  font: 20px/4px;
  width: 50px;
  width: 1.5;
  height: 25px;
  margin-left: 13px;
}
           

颜色值运算

颜色值的运算是分段计算进行的,也就是分别计算红色,绿色,以及蓝色的值:

p {
    color: #010203 + #040506;
    color: #010203 * 2;
}
           

计算

01 + 04 = 05

02 + 05 = 07

03 + 06 = 09

01 * 2 = 02

02 * 2 = 04

03 * 2 = 06

然后编译为:

/* css */
p {
    color: #050709; 
    color: #020406;}
           

字符串运算

p {
  content: 'sa' + 'sb';
  cursor: 'sa' - 'sb';
}
           

编译为:

/* css */
p {
  content: "sasb";
  cursor: "sa"-"sb";
}
           

布尔运算

Sass支持布尔型的

and

or

以及

not

运算。

p {
  content: 'sa' and 'sb';
  cursor: 'sb' or 1;
  right: 1 not 2;
  clear: 'sa' or 'sb';
}
           

编译为:

/* css */
p {
  content: "sb";
  cursor: "sb";
  right: 1 false;
  clear: "sa";
}
           

数组运算

数组不支持任何运算方式

混合-Mixins

sass中使用@mixin声明混合,可以传递参数,参数名以$符号开始,mixin可以传入参数,多个参数以逗号分开,也可以给参数设置默认值。

mixin是可以重用的一组CSS声明。mixin有助于减少重复代码,只需声明一次,就可在文件中引用。mixin类似变量,不同的是变量存储值,mixin存储一组css声明。

表达式

@mixin 名字(参数1,参数2...){
	...
}
           

调用方式:使用

@include

指令后跟mixin的名称

实例:

@mixin alert ($text-color, $background) {
  color: $text-color;
  background-color: $background;
  a {
    color: darken($text-color, 10%);
  }
}
.alert-warning {
  @include alert(#555555,#c03737);
}
           

编译为:

/* css */
.alert-warning {
  color: #555555;
  background-color: #c03737;
}
.alert-warning a {
  color: #3c3c3c;
}
           

控制语句

Sass 提供了一些基础的控制指令,比如在满足一定条件时引用样式,或者设定范围重复输出格式。控制指令是一种高级功能,日常编写过程中并不常用到,主要与混合指令 (mixin) 配合使用。

@if

表达式

@if 条件 {
	...
}
           

@if

的表达式返回值不是

false

或者

null

时,条件成立,输出

{}

内的代码:

p {
  @if 1 + 1 == 2 { border: 1px solid; }
  @if 5 < 3 { border: 2px dotted; }
  @if null  { border: 3px double; }
}
           

编译为:

/* css */
p {
  border: 1px solid; }
           

@if

声明后面可以跟多个

@else if

声明,或者一个

@else

声明。如果

@if

声明失败,Sass 将逐条执行

@else if

声明,如果全部失败,最后执行

@else

声明,例如:

$type: monster;
p {
  @if $type == ocean {
    color: blue;
  } @else if $type == matador {
    color: red;
  } @else if $type == monster {
    color: green;
  } @else {
    color: black;
  }
}
           

编译为:

/* css */
p {
  color: green; }
           

@for

表达式

@for $var from <开始值> though <结束值> {
    ...
}
           

@for

指令可以在限制的范围内重复输出格式,每次按要求(变量的值)对输出结果做出变动。

这个指令包含两种格式:

  • @for $var from <start> through <end>

  • @for $var from <start> to <end>

区别在于

through

to

的含义:当使用

through

时,条件范围包含

<start>

<end>

的值,而使用

to

时条件范围只包含

<start>

的值不包含

<end>

的值。另外,

$var

可以是任何变量,比如

$i

<start>

<end>

必须是整数值。

实例:

@for $j from 4 through 6 {
  .item-#{$j} { width: 2em * $j; }
}
           

编译为:

/* css */
.item-4 {
  width: 8em;}
.item-5 {
  width: 10em;}
.item-6 {
  width: 12em;}
           

@each

表达式

@each $var in $list {
	...
}
           

@each

指令的格式是

$var in <list>

,

$var

可以是任何变量名,比如

$length

或者

$name

,而

<list>

是一连串的值,也就是值列表。

@each

将变量

$var

作用于值列表中的每一个项目,然后输出结果。

实例:

@each $fruit in apple, banana, watermelon, strawberry {
  .#{$fruit}-icon {
    background-image: url('/images/#{$fruit}.png');
  }
}
           

编译为:

/* css */
.apple-icon {
  background-image: url("/images/apple.png");}
.banana-icon {
  background-image: url("/images/banana.png");}
.watermelon-icon {
  background-image: url("/images/watermelon.png");}
.strawberry-icon {
  background-image: url("/images/strawberry.png");}
           

@while

表达式

@while 条件 {
	...
}
           

@while

指令重复输出格式直到表达式返回结果为

false

。这样可以实现比

@for

更复杂的循环,只是很少会用到。

实例:

$j: 8;
@while $j >0 {
  .item-#{$j} {
    width: 2em * $j;
  }
  $j: $j - 3;
}
           

编译为:

/* css */
.item-8 {
  width: 16em;}
.item-5 {
  width: 10em;}
.item-2 {
  width: 4em;}
           

Partials与@import

@import

Sass 可以帮助我们减少 CSS 重复的代码,节省开发时间。

我们可以安装不同的属性来创建一些代码文件,如:变量定义的文件、颜色相关的文件、字体相关的文件等。

Sass 导入文件

类似 CSS,Sass 支持 @import 指令。

@import 指令可以让我们导入其他文件等内容。

CSS @import 指令在每次调用时,都会创建一个额外的 HTTP 请求。但,Sass @import 指令将文件包含在 CSS 中,不需要额外的 HTTP 请求。

Sass @import 指令语法如下:

@import filename;
// 例:
@import "base";
           

注意:包含文件时不需要指定文件后缀,Sass 会自动添加后缀 .scss。

局部文件(Partial)

Sass源文件中可以通过

@import

指令导入其他Sass源文件,被导入的文件就是局部文件,局部文件让Sass模块化编写更加容易。

如果一个目录正在被Sass程序监测,目录下的所有scss/sass源文件都会被编译,但通常不希望局部文件被编译,因为局部文件是用来被导入到其他文件的。如果不想局部文件被编译,文件名可以以下划线 (_)开头。

实例:

// _base.scss文件
body {
  margin: 0;
  padding: 0;
}
           
// test1.scss文件
@import "base";

@mixin alert ($text-color, $background) {
  color: $text-color;
  background-color: $background;
  a {
    color: darken($text-color, 10%);
  }
}
.alert-warning {
  @include alert(#555555, #c03737);
}
           

编译为:

/* css */
body {
  margin: 0;
  padding: 0;
}
.alert-warning {
  color: #555555;
  background-color: #c03737;
}
.alert-warning a {
  color: #3c3c3c;
}
           

函数

表达式

@function 名称 (参数1,参数2) {
	...
}
           

Sass 支持自定义函数,并能在任何属性值中使用:

$grid-width: 40px;
$gutter-width: 10px;

@function grid-width($n) {
  @return $n * $grid-width + ($n - 1) * $gutter-width;
}

#sidebar { width: grid-width(5); }
           

编译为:

/* css */
#sidebar {
  width: 240px; }
           

与 mixin 相同,也可以传递若干个全局变量给函数作为参数。一个函数可以含有多条语句,需要调用

@return

输出结果。自定义的函数也可以使用关键词参数,上面的例子还可以这样写:

#sidebar { width: grid-width($n: 5); }
           

建议在自定义函数前添加前缀避免命名冲突,其他人阅读代码时也会知道这不是 Sass 或者 CSS 的自带功能。自定义函数与 mixin 相同,都支持 variable arguments

Sass 颜色函数

Sass 颜色函数可以分为三个部分:颜色设置、颜色获取以及颜色操作。

Sass 颜色设置

函数 描述 & 实例
rgb(red, green, blue) 创建一个 Red-Green-Blue (RGB) 色。其中 R 是 “red” 表示红色,而 G 是 “green” 绿色,B 是 “blue” 蓝色。
实例: rgb(0, 0, 255);
rgba(red, green, blue, alpha) 根据红、绿、蓝和透明度值创建一个颜色。
实例: rgba(0, 0, 255, 0.3);
hsl(hue, saturation, lightness) 通过色相(hue)、饱和度(saturation)和亮度(lightness)的值创建一个颜色。
实例: hsl(120, 100%, 50%); // 绿色 hsl(120, 100%, 75%); // 浅绿色
hsla(hue, saturation, lightness, alpha) 通过色相(hue)、饱和度(saturation)、亮度(lightness)和透明(alpha)的值创建一个颜色。
实例: hsl(120, 100%, 50%, 0.3); // 绿色带有透明度 hsl(120, 100%, 75%, 0.3); // 浅绿色带有透明度
grayscale(color) 将一个颜色变成灰色,相当于 desaturate( color,100%)。
实例: grayscale(#7fffd4); 结果: #c6c6c6
complement(color) 返回一个补充色,相当于adjust-hue($color,180deg)。
实例: complement(#7fffd4); 结果: #ff7faa
invert(color, weight) 返回一个反相色,红、绿、蓝色值倒过来,而透明度不变。
实例: invert(white); 结果: black

@media

Sass 中

@media

指令与 CSS 中用法一样,只是增加了一点额外的功能:允许其在 CSS 规则中嵌套。如果

@media

嵌套在 CSS 规则内,编译时,

@media

将被编译到文件的最外层,包含嵌套的父选择器。这个功能让

@media

用起来更方便,不需要重复使用选择器,也不会打乱 CSS 的书写流程。

.component {
  width: 300px;
  @media (width: 567px) {
    width: 600px;
    @media  (resolution: 192dpi) {
      background-image: url(/img/1.png);
    }
  }
  @media (width: 1120px) {
    width: 400px;
  }
}
           

编译为:

/* css */
.component {
  width: 300px;
}
@media (width: 567px) {
  .component {
    width: 600px;
  }
}
@media (width: 567px) and (resolution: 192dpi) {
  .component {
    background-image: url(/img/1.png);
  }
}
@media (width: 1120px) {
  .component {
    width: 400px;
  }
}
           

继承(@extend)

sass中,选择器继承可以让选择器继承另一个选择器的所有样式,并联合声明。使用选择器的继承,要使用关键词@extend,后面紧跟需要继承的选择器。

.class1 {
    width: 200px;
}
.class2 {
    @extend .class1;
    background-color: #000;
}
           

编译为:

/* css */
.class1, .class2 {
  width: 200px;
}
.class2 {
  background-color: #000;
}
           

.class2

不仅会继承

.class1

自身的所有样式,也会继承任何跟

.class1

有关的组合选择器样式,实例如下:

.class1 {
    width: 200px;
}
.class1 a {
    color: white;
}
.class2 {
    @extend .class1;
}
           

编译为:

/* css */
.class1, .class2 {
  width: 200px;
}
.class1 a, .class2 a {
  color: white;
}
           

警告与错误

当错误使用函数或mixins时可以看到警告或错误提示信息

$color: (
  light:#ffffff,
  dark:#000000
);

@function color($key) {
  @if not map-has-key($colors, $key) {
    @warn "在 $colors 里没找到 #{$key} 这个key";
  }

  @return map-get($colors, $key);
}
body {
  background-color: color(gray);
}
// 在命令行窗口显示:
// WARNING:在 $colors 里没找到 gray 这个key

// 把@warn改为@error,会在css文件中出现错误信息
           

了解更多

想更多更详细了解sass可以浏览:

官网:Sass: Syntactically Awesome Style Sheets (sass-lang.com)

中文官网:Sass教程 Sass中文文档 | Sass中文网