sass学习笔记

Sass编译风格

sass --watch test.scss:test.css --style expanded
sass --watch test.scss:test.css --style compact
sass --watch test.scss:test.css --style compressed

Sass变量

声明变量:在Sass中所有的变量都使用美元符号“$”开头。 默认变量:sass 的默认变量仅需要在值后面加上 !default 即可。

$brand-primary : darken(#428bca, 6.5%) !default; // #337ab7
$btn-primary-color : #fff !default;
$btn-primary-bg : $brand-primary !default;
$btn-primary-border : darken($btn-primary-bg, 5%) !default;

sass 控制指令

1、@if

2、@for

语法1:从开始循环,到结束,变量$var包括边界值.

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

语法2:循环从开始,一直遍历循环到结束。这种形式的循环只要碰到就会停止循环(将不会遍历值)。

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

3、@each

语法:

@each $var in

4、@while

@whild指令也需要SassScript表达式(像其他指令一样),并且会生成不同的样式块,直到表达式值为false时停止循环。这个和@for指令很相似,只要@while后面的条件为true就会执行。

Sass Map

Sass的map使用一个括号,并用冒号将键值与值分隔开来,并且使用逗号将一对键值/值隔开。下面是一个有效的Sass的map

$map: (
  key: value,
  other-key: other-value
);

声明混合宏

在 Sass 中通过 @mixin 关键词声明了一个混合宏,那么在实际调用中,其匹配了一个关键词“@include”来调用声明好的混合宏。

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

实际调用混合宏是:

.box-center {
  @include center(500px,300px);
}

####混合宏的不足 混合宏在实际编码中给我们带来很多方便之处,特别是对于复用重复代码块。但其最大的不足之处是会生成冗余的代码块。比如在不同的地方调用一个相同的混合宏时。如:

@mixin border-radius{
  -webkit-border-radius: 3px;
  border-radius: 3px;
}

.box {
  @include border-radius;
  margin-bottom: 5px;
}

.btn {
  @include border-radius;
}

示例在“.box”和“.btn”中都调用了定义好的“border-radius”混合宏。先来看编译出来的 CSS:

box {
  -webkit-border-radius: 3px;
  border-radius: 3px;
  margin-bottom: 5px;
}

.btn {
  -webkit-border-radius: 3px;
  border-radius: 3px;
}

上例明显可以看出,Sass 在调用相同的混合宏时,并不能智能的将相同的样式代码块合并在一起。这也是 Sass 的混合宏最不足之处。

####什么时候使用Mixins

Mixins的黄金规则是将相似的风格定义在一个@mixin中。请注意这里的一个关键词相似的,另外Mixins主要是用于重用,而不是用来指定具体的属性值。例如这个实例,我们应该用@mxin来创建不同半径的圆角,而不是用来创建一个具体值的@mixin。换句话来说,如果你创建的Mixins没有传参数,那您就是一种错误的使用方法。基于这点出发,我们可以把上例中的@mixin rounded传入一个$radius参数:

@mixin rounded($radius){
    -webkit-border-radius: $radius;
    -moz-border-radius: $radius;
    -o-border-radius: $radius;
    -ms-border-radius: $radius;
    border-radius: $radius;
}

在@mixin中,我们除了可以传参之外,还可以给参数设置一个默认值:

@mixin rounded($radius:5px){
    -webkit-border-radius: $radius;
    -moz-border-radius: $radius;
    -o-border-radius: $radius;
    -ms-border-radius: $radius;
    border-radius: $radius;
}

如此一来,我们就可以在调用的时候传入不同的参数值,当然,要是传入的参数值是一样的,同样会出现上面的现象。这是使用Mixins无法避免的。

扩展与继承

在 Sass 中也具有继承一说,也是继承类中的样式代码块。在 Sass 中是通过关键词 “@extend”来继承已存在的类样式块,从而实现代码的继承。如下所示:

//SCSS
.btn {
  border: 1px solid #ccc;
  padding: 6px 10px;
  font-size: 14px;
}

.btn-primary {
  background-color: #f36;
  color: #fff;
  @extend .btn;
}

.btn-second {
  background-color: orange;
  color: #fff;
  @extend .btn;
}

编译出来之后:

//CSS
.btn, .btn-primary, .btn-second {
  border: 1px solid #ccc;
  padding: 6px 10px;
  font-size: 14px;
}

.btn-primary {
  background-color: #f36;
  color: #fff;
}

.btn-second {
  background-clor: orange;
  color: #fff;
}

从示例代码可以看出,在 Sass 中的继承,可以继承类样式块中所有样式代码,而且编译出来的 CSS 会将选择器合并在一起,形成组合选择器。

继承的缺点

SASS的继承,可以将相同样式规则定义在一个类中,然后能过@extend来调用。这样就可以把相同样式合并在一起。按照这个原理,我们可以把上面的@mixin rounded替换成.rounded,然后在需要的地方通过@extend来调用.rounded。这样就可以解决使用@mixin致使样式重复出现多次的问题。

.button {
    display: block;
    padding: 10px;
    background: green;
}

.sidebar .signup .button {
    margin-top: 20px;
}

.registrantion,
.remember-password {
    .button {
        margin-bottom: 33px;
    }
}

.edit-account .delete-area .button {
    background-color: red;
    color: white;
}

.article a {
    @extend .button;
}

在上面这段简单的SASS代码中.button一共出现过四次,我们来看编译出来的CSS代码:

.button, .article a {
  display: block;
  padding: 10px;
  background: green;
}

.sidebar .signup .button,
.sidebar .signup .article a,
.article .sidebar .signup a {
  margin-top: 20px;
}

.registrantion .button,
.registrantion .article a,
.article .registrantion a,
.remember-password .button,
.remember-password .article a,
.article .remember-password a {
  margin-bottom: 33px;
}

.edit-account .delete-area .button,
.edit-account .delete-area .article a,
.article .edit-account .delete-area a {
  background-color: red;
  color: white;
}

转译出来的CSS可能出乎你的意外,你原本可能只需要转译出来这样的代码:

.button, .article a {
  display: block;
  padding: 10px;
  background: green;
}

这可能让你大失所望。.button类名可能用在不同之处,有不同的容器包裹着,然而SASS中的@extend无法判断引用哪个地方的.button。所以他自己做主,将不同地方出现的.button类名都引入了进来,也就造成了上述你不想看到的现象。所以在使用SASS继承时有一个规则:

通过@extend引用的类名,你要有绝对的自信,它从未用在几个地方。

占位符 %placeholder

首先使用%placeholders定义一个公用样式,类似于.class`

%placeholders {/*公用样式*/}

在需要使用的地方通过@extend来调用:

selector {
    @extend %placeholders;
}

他可以取代以前 CSS 中的基类造成的代码冗余的情形。因为 %placeholder 声明的代码,如果不被 @extend 调用的话,不会产生任何代码。这样,我们就可以把前面使用.button隐藏的地雷给拔了。我们只需要定义一个%button,并用@extend来调用:

.button,
%button {
    display: block;
    padding: 10px;
    background: green;
}

.sidebar .signup .button {
    margin-top: 20px;
}

.registrantion,
.remember-password {
    .button {
        margin-bottom: 33px;
    }
}

.edit-account .delete-area .button {
    background-color: red;
    color: white;
}

.article a {
    @extend %button;
}

这样编译出来的CSS,就是你想要的结果了:

.button,
.article a {
  display: block;
  padding: 10px;
  background: green;
}

.sidebar .signup .button {
  margin-top: 20px;
}

.registrantion .button,
.remember-password .button {
  margin-bottom: 33px;
}

.edit-account .delete-area .button {
  background-color: red;
  color: white;
}

从编译出来的 CSS 代码可以看出,通过 @extend 调用的占位符,编译出来的代码会将相同的代码合并在一起。这也是我们希望看到的效果,也让你的代码变得更为干净。

Mixins与%placeholders的结合

Mixins如果使用不当,就会产生很多重复的代码,但仅用@extend很多时候又无法达到功能上的需求。那么有没有方法能把Mixins%placeholders结合起来,取他们各自的优势呢?

大家都知道 %placeholder 类似于CSS中的 .classes 或者 #id ,只不过使用 %placeholder代替了 .#。但 %placeholder中的代码只有通过 @extend 调用后才会产生代码。

使用Mixins和%placeholder生成生成网格系统的例子

$columns: 12;
$gutter: 2em;

%grid{
  box-sizing: border-box;
  display:inline-block;
  padding:{
    left: $gutter/2;
    right: $gutter/2;
  }
}

@mixin grid($width:1){
  @extend %grid;
  width: percentage($width);
}

@for $column from 1 through $columns{
  .grid-#{$column} {
    @include grid(1/$column);
  }
}

####插值#{}

####颜色函数

列表

Sass中的列表索引值和JavaSctript数组中的索引值不一样,他是从1开始,而不是从0开始。一旦你开始使用Sass列表,这个问题也是最容易出错的。

nth($list,0) => throws error
nth($list,1) => item-1

在Sass中每一个值都可以是一个列表。字符串、数值、布尔值或者任何变量。而且可以通过Sass的List函数来检测出一些值。

我们来看一个简单的例子:

$variable: "Sass is awesome";
$variable2: Sass is awesome;

上面两个变量值仅仅就是一个有引号,一个没有引号。

使用type-of()函数检测出他们的类型:

>> type-of($variable)
"string"
>> type-of($variable2)
"list"
>>

使用length()函数检测出他们的长度:

>> length($variable)
1
>> length($variable2)
3

在用nth()函数来检测输出内容:

>> nth($variable,1)
"Sass is awesome"
>> nth($variable2,1)
"Sass"
>>

####Sass列表应用

比如说一个扩展选择器,如:

.home .nav-home,
.about .nav-about,
.products .nav-products,
.contact .nav-contact

这些选择器都是基于列表的关键值生成:

$pages: home,about,products,contact;

根据这个列表,有三种方法可以生成这样的选择器,我们可以一个一个来看。

I、长而复杂的方法,它可以运行,但它需要一个额外的条件来处理逗号。如:

$pages: home,about,products,contact;
$selector:();
@each $item in $pages{
  $selector: $selector unquote(".#{$item} .nav-#{$item}");
  @if $item != nth($pages, length($pages)){
      $selector: $selector unquote(",");
  }
}

基本上给$selector添加了新的选择器,如果我们不处理列表的最后一项,我们需要添加一个逗号。

II、简洁的方法,这种方法是通过append()函数方法,将他们添加到一起。这也是最简单的方法。

$pages: home,about,products,contact;
$selector:();
@each $item in $pages{
    $selector: append($selector,unquote(".#{$item} .nav-#{$item}"),comma);
}

我认为这是很简单的,我们将显示的使用逗号将选择器与前面的分隔开,并将此重新赋以给新的选择器$selector。

III、隐式的方法,这种方法是最简单的,通过隐式的附加功能,将选择器合在一起,非常的简洁。

$pages: home,about,products,contact;
$selector:();
@each $item in $pages{
    $selector: $selector,unquote(".#{$item} .nav-#{$item}");
}