Sass

6/28/2020 Sass

# Sass简介

Sass 是一种 CSS 的预编译语言。它提供了 变量(variables)、嵌套(nested rules)、 [混合(mixins)]、 函数(functions)等功能,并且完全兼容 CSS 语法。Sass 能够帮助复杂的样式表更有条理, 并且易于在项目内部或跨项目共享设计。

# Sass和Less

Sass和Less都属于CSS预处理器。但是Sass比Less要更加强大。

# Sass与Scss

Scss 是 Sass 3 引入新的语法,其语法完全兼容 CSS3,并且继承了 Sass 的强大功能。可以简单理解为Scss是Sass的一个升级版本,完全兼容sass之前的功能,又有了些新增能力。语法形式上有些许不同。

# 变量

sass让人们受益的一个重要特性就是它为css引入了变量。你可以把反复使用的css属性值 定义成变量,然后通过变量名来引用它们,而无需重复书写这一属性值。或者,对于仅使用过一 次的属性值,你可以赋予其一个易懂的变量名,让人一眼就知道这个属性值的用途。

# 变量声明

sass变量的声明和css属性的声明很像:

$highlight-color: #F90;
1

# 变量引用

凡是css属性的标准值(比如说1px或者bold)可存在的地方,变量就可以使用。css生成时,变量会被它们的值所替代。之后,如果你需要一个不同的值,只需要改变这个变量的值,则所有引用此变量的地方生成的值都会随之改变。

$highlight-color: #F90;
.selected {
  border: 1px solid $highlight-color;
}

//编译后

.selected {
  border: 1px solid #F90;
}
1
2
3
4
5
6
7
8
9
10

# 嵌套CSS 规则

scss写法

#content {
  article {
    h1 { color: #333 }
    p { margin-bottom: 1.4em }
  }
  aside { background-color: #EEE }
}
1
2
3
4
5
6
7

==>

 /* 编译后 */css
#content article h1 { color: #333 }
#content article p { margin-bottom: 1.4em }
#content aside { background-color: #EEE }
1
2
3
4

# 父选择器的标识符&

&会被解释为父选择器

article a {
  color: blue;
  &:hover { color: red }
}
1
2
3
4

==>

article a { color: blue }
article a:hover { color: red }
1
2

# 群组选择器的嵌套

nav, aside {
  a {color: blue}
}
1
2
3

==>

nav a, aside a {color: blue}
1

# 子组合选择器和同层组合选择器:>、+和~

article {
  ~ article { border-top: 1px dashed #ccc }
  > section { background: #eee }
  dl > {
    dt { color: #333 }
    dd { color: #555 }
  }
  nav + & { margin-top: 0 }
}
1
2
3
4
5
6
7
8
9

==>

article ~ article { border-top: 1px dashed #ccc }
article > footer { background: #eee }
article dl > dt { color: #333 }
article dl > dd { color: #555 }
nav + article { margin-top: 0 }
1
2
3
4
5

# 嵌套属性

Eg.1

nav {
  border: {
  style: solid;
  width: 1px;
  color: #ccc;
  }
}
1
2
3
4
5
6
7

==>

nav {
  border-style: solid;
  border-width: 1px;
  border-color: #ccc;
}
1
2
3
4
5

Eg.2

nav {
  border: 1px solid #ccc {
  left: 0px;
  right: 0px;
  }
}
1
2
3
4
5
6

==>

nav {
  border: 1px solid #ccc;
  border-left: 0px;
  border-right: 0px;
}
1
2
3
4
5

# 导入SASS文件

css有一个特别不常用的特性,即@import规则,它允许在一个css文件中导入其他css文件。然而,后果是只有执行到@import时,浏览器才会去下载其他css文件,这导致页面加载起来特别慢。

sass也有一个@import规则,但不同的是,sass@import规则在生成css文件时就把相关文件导入进来。这意味着所有相关的样式被归纳到了同一个css文件中,而无需发起额外的下载请求。另外,所有在被导入文件中定义的变量和混合器均可在导入文件中使用。

# 使用SASS部分文件

当通过@importsass样式分散到多个文件时,你通常只想生成少数几个css文件。那些专门为@import命令而编写的sass文件,并不需要生成对应的独立css文件,这样的sass文件称为局部文件。对此,sass有一个特殊的约定来命名这些文件(sass局部文件的文件名以下划线开头。)

举例来说,你想导入themes/_night-sky.scss这个局部文件里的变量,你只需在样式表中写@import "themes/night-sky";

# 默认变量值

sass!default标签,它很像css属性中!important标签的对立面,不同的是!default用于变量,含义是:如果这个变量被声明赋值了,那就用它声明的值,否则就用这个默认值。

$fancybox-width: 400px !default;
.fancybox {
width: $fancybox-width;
}
1
2
3
4

在上例中,如果用户在导入你的sass局部文件之前声明了一个$fancybox-width变量,那么你的局部文件中对$fancybox-width赋值400px的操作就无效。如果用户没有做这样的声明,则$fancybox-width将默认为400px

# 嵌套导入

_blue-theme.scss

aside {
  background: blue;
  color: white;
}
1
2
3
4

把它导入到一个CSS规则内,如下所示:

.blue-theme {@import "blue-theme"}
1

==>

.blue-theme {
  aside {
    background: blue;
    color: #fff;
  }
}
1
2
3
4
5
6

# 原生的CSS导入

由于sass兼容原生的css,所以它也支持原生的CSS@import。尽管通常在sass中使用@import时,sass会尝试找到对应的sass文件并导入进来,但在下列三种情况下会生成原生的CSS@import,尽管这会造成浏览器解析css时的额外下载:

  • 被导入文件的名字以.css结尾;
  • 被导入文件的名字是一个URL地址(比如http://www.sass.hk/css/css.css),由此可用谷歌字体API提供的相应服务;
  • 被导入文件的名字是CSS的url()值。

这就是说,你不能用sass@import直接导入一个原始的css文件,因为sass会认为你想用css原生的@import。但是,因为sass的语法完全兼容css,所以你可以把原始的css文件改名为.scss后缀,即可直接导入了。

# 静默注释

sass另外提供了一种不同于css标准注释格式/* ... */的注释语法,即静默注释,其内容不会出现在生成的css文件中

body {
  color: #333; // 这种注释内容不会出现在生成的css文件中
  padding: 0; /* 这种注释内容会出现在生成的css文件中 */
}
1
2
3
4

# 混合器

混合器使用@mixin标识符定义。看上去很像其他的CSS @标识符,比如说@media或者@font-face。这个标识符给一大段样式赋予一个名字,这样你就可以轻易地通过引用这个名字重用这段样式。

定义混合器

@mixin rounded-corners {
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  border-radius: 5px;
}
1
2
3
4
5

引用混合器

notice {
  background-color: green;
  border: 2px solid #00aa00;
  @include rounded-corners;
}
1
2
3
4
5

==>

.notice {
  background-color: green;
  border: 2px solid #00aa00;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  border-radius: 5px;
}
1
2
3
4
5
6
7

# 给混合器传参

混合器并不一定总得生成相同的样式。可以通过在@include混合器时给混合器传参,来定制混合器生成的精确样式。当@include混合器时,参数其实就是可以赋值给css属性值的变量。

@mixin link-colors($normal, $hover, $visited) {
  color: $normal;
  &:hover { color: $hover; }
  &:visited { color: $visited; }
}
1
2
3
4
5

当混合器被@include时,你可以把它当作一个css函数来传参。如果你像下边这样写:

a {
  @include link-colors(blue, red, green);
}
1
2
3

==>

a { color: blue; }
a:hover { color: red; }
a:visited { color: green; }
1
2
3

当你@include混合器时,有时候可能会很难区分每个参数是什么意思,参数之间是一个什么样的顺序。为了解决这个问题,sass允许通过语法$name: value的形式指定每个参数的值。这种形式的传参,参数顺序就不必再在乎了,只需要保证没有漏掉参数即可:

a {
    @include link-colors(
      $normal: blue,
      $visited: green,
      $hover: red
  );
}
1
2
3
4
5
6
7

# 默认参数值

为了在@include混合器时不必传入所有的参数,我们可以给参数指定一个默认值。参数默认值使用$name: default-value的声明形式,默认值可以是任何有效的css属性值,甚至是其他参数的引用。

# 选择器继承

使用sass的时候,最后一个减少重复的主要特性就是选择器继承。基于Nicole Sullivan面向对象的css的理念,选择器继承是说一个选择器可以继承为另一个选择器定义的所有样式。这个通过@extend语法实现,如下代码:

//通过选择器继承继承样式
.error {
  border: 1px solid red;
  background-color: #fdd;
}
.seriousError {
  @extend .error;
  border-width: 3px;
}
1
2
3
4
5
6
7
8
9

.seriousError不仅会继承.error自身的所有样式,任何跟.error有关的组合选择器样式也会被.seriousError以组合选择器的形式继承,如下代码:

//.seriousError从.error继承样式
.error a{  //应用到.seriousError a
  color: red;
  font-weight: 100;
}
h1.error { //应用到hl.seriousError
  font-size: 1.2rem;
}
1
2
3
4
5
6
7
8

如上所示,在class="seriousError"html元素内的超链接也会变成红色和粗体。

# 继承的高级用法

略...感兴趣的参考文档 (opens new window)

# 最后

至此,sass最基本部分已经介绍完了,通过这些基础知识,你已经可以尝试去使用sass来精简你的css了。