Sass教程

218 阅读5分钟

简介

Sass是一种css的预处理器语言。在css的功能上增加了变量,嵌套 ,混合混入,继承等,也能很好的扩展css。使用sass可以很好的管理项目的样式文件,更高效的开发 项目

变量

sass变量使用$符号,赋值和css属性值一样

$color:red;
body {
  color: $color
}

// 编译后
body {
  color: red;
}

变量支持块级作用域,全局环境无法使用局部定义的变量,若要使用则必须后面加上!global;

p {
  $width: 5px!global;
  width: $width;
}
div {
  width: $width;
}

// 编译后
p {
  width: 5px;
}
div {
  width: 5px;
}

变量可以很好的管理项目中样式的尺寸和主题色等,不需要把所有的都改一遍,只要改变变量值就可以。

嵌套

嵌套就是允许一套样式嵌套在另一套样式中,然后将外层的选择器作为父选择器。嵌套也避免了重复输入父选择器,使得样式结构清晰。

div {
  .box {
    font-size: 16px;
  }
}

// 编译为
div .box {
  font-size: 16px;
}

在一些选择器上,比如某一元素上hover效果,或者是伪类伪元素,还有一个元素上有多个css类名,我们可以使用 & 符号来表示嵌套规则的父选择器。如果含有多层嵌套,最外层的父选择器会一层一层向下传递。

a {
  &:hover {
    color: red;
  }
  &.link {
    color: blue;
  }
  .nav {
    &:hover {
      color: red;
    }
  }
  &__box {
    font-size: 16px;
  }
}

// 编译为
a:hover {
  color: red;
}
a.link {
  color: blue;
}
a .nav:hover {
  color: red;
}
a__box {
  font-size: 16px;
}

Mixin(混入)

mixin 混合是为了可以重复使用样式。引用mixin 使用@include,也可以传参来改变属性值。

@mixin small-size {
  font-size: 12px;
  color: red;
}

p {
  @include small-size;
  padding-top: 4px;
}

// 编译后
p {
  font-size: 12px;
  color: red;
  padding-top: 4px;
}

混合样式中也可以包含其他混合样式。

@mixin size {
  font-size: 12px;
}
@mixin color {
  color: red;
}
@mixin text-style {
  @include sizz;
  @include color;
}

混合还可以使用参数,参数之间使用逗号隔开,使用时候写入相应的参数。参数还可以使用默认值。

@mixin text($size, $color) {
  font-size: $size;
  color: $color;
}

@mixin text-1($size, $color:red) {
  font-size: $size;
  color: $color;
}

p {
  @include text(12px, blue)
}

p {
  @include text-1(12px)
}

// 编译后
p {
  font-size: 12px;
  color: blue;
}

p {
  font-size: 12px;
  color: red;
}

继承扩展

在网页开发中会经常有一个元素的样式和另一个元素的样式完全一样,这样会产生额外代码。所以用继承来避免这样的问题

.error {
  border: 1px solid red;
}

.linkerror {
  @extend .error;
  border-width: 3px;
}

// 编译后
.error,.linkerror {
  border: 1px solid red;
}
.linkerror {
  border-width: 3px;
}

多重延伸

.error {
  border: 1px #f00;
}
.like {
  font-size: 12px;
  background-color: #ff0;
}
.seriousError {
  @extend .error;
  @extend .like;
  border-width: 3px;
}

// 编译后
.error, .seriousError {
  border: 1px #f00;
}

.like, .seriousError {
  font-size: 12px;
  background-color: #ff0;
}

.seriousError {
  border-width: 3px;
}

继续延伸,当一个选择器延伸给第二个后,可以继续将第二个选择器延伸给第三个。

.error {
  border: 1px #f00;
}
.link {
  @extend .error;
  border-width: 3px;
}
.like {
  @extend .link;
  font-size: 12px;
}

// 编译后
.error, .link, .like {
  border: 1px #f00;
}
.link, .like {
  border-width: 3px;
}
.like {
  font-size: 12px;
}

运算

加法

p {
  font-size: 12px + 12px;
}
// 编译后
p {
  font-size: 24px;
}

减法

p {
  font-size: 12px - 12px;
}
// 编译后
p {
  font-size: 0px;
}

乘法

p {
  $width: 30px;
  width: $width * 2;
}
// 编译后
p {
  width: 60px;
}

除法

p {
  $width: 30px;
  width: $width / 2;
}
// 编译后
p {
  width: 15px;
}

插值语句 #{}

p {
  $name: footer;
  $aut: border;
  .#{$name} {
  	#{$aut}: 1px solid red;
  }
}
// 编译后
p .footer {
  border: 1px solid red;
}

// 计算中的运用
p {
  &:hover {
    &::before {
      content: '计算1+1=#{1+1}';
    }
  }
}
// 编译后
p:hover::before {
  content: "计算1+1=2";
}

@import

@import 会寻找.scss或者.sass文件,但是一下情况会认为是普通css语句,并不会去寻找sass文件

  • 文件扩展名是.css
  • 文件名是http开头
  • 文件名是url
  • 不能包含媒体查询 media queries

@import 可以导入扩展名 为.scss和.sass文件,如果没有扩展名,sass会寻找同名文件扩展名为.scss或者.sass文件导入

@import 'common.scss';
// 或者
@import 'common';

Sass还可以将文件作为一个组件来使用,并且当前文件不会被单独编译成css文件,要想实现这个功能,只要在命名的时候在前面加下划线就行。只有这个文件在另一个sass文件中被引用才会被编译成文件。有了这一功能后,我们可以把公共变量的,公共@mixin, 公共@function等等提取出来,然后在哪里需要的地方引入就行,非常有利用我们模块化开发。

@import 还可以用于嵌套

// style.scss 文件
.style {
  color:red;
}

.link {
  @import 'style';
}

// 编译后
.link .style {
  color: red;
}

@media

sass中的@media和css规则中的用法一样,只是增加了一点点功能,允许在css规则中嵌套。如果@media在css规则中嵌套了,编译的时候会编译到最外层,并且包括嵌套的父层选择器。

.link {
  .sidebar {
    width: 300px;
    @media screen and (orientation: landscape) {
      width: 500px;
    }
  }
}

// 编译后
.link .sidebar {
  width: 300px;
}

@media screen and (orientation: landscape) {
  .link .sidebar {
    width: 500px;
  }
}

@media 的 queries 允许互相嵌套使用,编译时,Sass 自动添加 and

@media screen {
  .sidebar {
    @media (orientation: landscape) {
      width: 500px;
    }
  }
}

// 编译后
@media screen and (orientation: landscape) {
  .sidebar {
    width: 500px;
  }
}

@if

当 @if 的表达式返回值不是 false 或者 null 时,条件成立,输出 {} 内的代码。

p {
  @if (1+1) < 3 {
    color: red;
  }
  @if (1+1) ==2 {
    color: #fff;
  }
  @if null {
    color: black;
  }
}

// 编译后
p {
  color: red;
  color: #fff;
}

@if 声明后面可以跟多个 @else if 声明,或者一个 @else 声明。如果 @if 声明失败,Sass 将逐条执行 @else if 声明,如果全部失败,最后执行 @else 声明

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

// 编译后
p {
  color: green;
}

@for 循环

@for 指令可以在限制的范围内重复输出格式,每次按要求(变量的值)对输出结果做出变动。这个指令包含两种格式:

1. @for $var from (start) through (end)
@for $i from 1 through 3 {
  .item-#{$i} { 
    width: 2em * $i;
  }
}

// 编译后
.item-1 {
  width: 2em;
}

.item-2 {
  width: 4em;
}

.item-3 {
  width: 6em;
}
2. @for $var from (start) to (end)
@for $i from 1 through 3 {
  .item-#{$i} { 
    width: 2em * $i;
  }
}

// 编译后
.item-1 {
  width: 2em;
}
.item-2 {
  width: 4em;
}

through 与 to的区别在于,使用through, 条件范围值包含start和end的值,使用to条件范围值只包含start值不包括end值,$var变量可以任意定义,比如$i。start和end值必须是整数

@each

@each 指令的格式是 $var in <list>, $var 可以是任何变量名,比如 $length 或者 $name,而 <list> 是一连串的值,也就是值列表。

1. 单个变量

@each $animal in puma, sea-slug, egret, salamander {
  .#{$animal}-icon {
    background-image: url('/images/#{$animal}.png');
  }
}

// 编译后
.puma-icon {
  background-image: url("/images/puma.png");
}
.sea-slug-icon {
  background-image: url("/images/sea-slug.png");
}
.egret-icon {
  background-image: url("/images/egret.png");
}
.salamander-icon {
  background-image: url("/images/salamander.png");
}

2.多个变量

@each $animal, $color, $cursor in (puma, black, default),
                                  (sea-slug, blue, pointer),
                                  (egret, white, move) {
  .#{$animal}-icon {
    background-image: url('/images/#{$animal}.png');
    border: 2px solid $color;
    cursor: $cursor;
  }
}
// 编译后
.puma-icon {
  background-image: url("/images/puma.png");
  border: 2px solid black;
  cursor: default;
}
.sea-slug-icon {
  background-image: url("/images/sea-slug.png");
  border: 2px solid blue;
  cursor: pointer;
}
.egret-icon {
  background-image: url("/images/egret.png");
  border: 2px solid white;
  cursor: move;
}

3. 映射

@each $header, $size in (h1: 2em, h2: 1.5em, h3: 1.2em) {
  #{$header} {
    font-size: $size;
  }
}

// 编译后
h1 {
  font-size: 2em;
}
h2 {
  font-size: 1.5em;
}
h3 {
  font-size: 1.2em;
}

@while

@while 指令重复输出格式直到表达式返回结果为 false。这样可以实现比 @for 更复杂的循环,只是很少会用到。

$i: 6;
@while $i > 0 {
  .item-#{$i} {
    width: 2em * $i;
  }
  $i: $i - 2;
}

// 编译后
.item-6 {
  width: 12em;
}
.item-4 {
  width: 8em;
}
.item-2 {
  width: 4em;
}

函数指令 @function

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

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

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

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

// 编译后
#sidebar {
  width: 240px;
}

注释 /* *///

Sass 支持标准的 CSS 多行注释 /* */,以及单行注释 // ,前者会 被完整输出到编译后的 CSS 文件中,而后者则不会。