Skip to content

Sass 语法规则

@debug*@error*@warn

注意

SASS中的@debug@error@warn分别和JavaScript中的console.log()console.error()console.warn()类似。

  • @debug可以打印一些信息,在这调试一些表达式或变量值的时候非常有用,如下:
scss
@mixin position($name, $position, $topOrBottom, $leftOrRight) {
  @debug $name, $position;
  #{$name}.is-#{$position} {
    position: $position;
    #{$topOrBottom}: 0;
    #{$leftOrRight}: 0;
  }
}
@include position('.box', 'absolute', 'top', 'left');

// 打印内容
index.scss:2 Debug: ".box", "absolute"
  • @warn@error通常用来对外部传入的值进行校验,看是否符合规范,如果不符合则提示警告信息和报错信息,例如:
ts
@mixin position($name, $position, $topOrBottom, $leftOrRight) {
  @if $position != 'relative' and $position != 'absolute' {
    @warn 'position must be relative or absolute'
  };
  @if $topOrBottom != 'top' and $topOrBottom != 'bottom' {
    @error 'topOrBottom must be top or bottom'
  };
  #{$name}.is-#{$position} {
    position: $position;
    #{$topOrBottom}: 0;
    #{$leftOrRight}: 0;
  }
}
@include position('.box', 'fixed', 'top1', 'left');

// 警告内容
Warning: "position must be relative or absolute"
// 报错内容
Error: "topOrBottom must be top or bottom"

@if和@else

SASS中的@if/@else和JavaScript中的if/else规则是一样的,例如:

scss
@mixin triangle($size, $color, $direction) {
  width: 0;
  height: 0;
  border-color: transparent;
  border-style: solid;
  border-width: calc($size / 2);

  @if $direction == "top" {
    border-top-color: $color;
  } @else if ($direction == "bottom") {
    border-bottom-color: $color;
  } @else if ($direction == "left") {
    border-left-color: $color;
  } @else if ($direction == "right") {
    border-right-color: $color;
  } @else {
    @warn 'direction must be top, bottom, left or right';
  }
}

.box {
  @include triangle(10px, "#f60", "right");
}
  • @if@else if也能使用SASS中的notorand,例如:
scss
@mixin triangle($size, $color, $direction) {
  $directions: top, bottom, left, right;
  width: 0;
  height: 0;
  border-color: transparent;
  border-style: solid;
  border-width: calc($size / 2);

  // index为全局内置函数,判断$direction是否在$directions值的集合中,是则返回索引,否则返回null
  @if not index($directions, $direction) {
    @warn 'direction must be top, bottom, left or right';
  } @else {
    border-#{$direction}-color: $color;
  }
}

.box {
  @include triangle(10px, "#f60", "right");
}
  • 以上代码编译为
css
.box {
  width: 0;
  height: 0;
  border-color: transparent;
  border-style: solid;
  border-width: 5px;
  border-right-color: "#f60";
}

@each

注意

SASS中的@each和JavaScript中的forEach()类似

SASS中的@each通常是用来迭代一个list或者map的,其公式为:@each <variable> in <expression>

scss
// 这是一个list列表
$sizes: 10px, 20px, 30px, 40px;

@each $size in $sizes {
  .box-#{$size} {
    width: $size;
    height: $size;
  }
}
  • 编译结果
css
.box-10px {
  width: 10px;
  height: 10px;
}
.box-20px {
  width: 20px;
  height: 20px;
}
.box-30px {
  width: 30px;
  height: 30px;
}
.box-40px {
  width: 40px;
  height: 40px;
}
  • @each也可以用来迭代key/value形式的map结构,例如:
css
$sizeMap: (
 h1: 20px,
 h2: 16px,
 h3: 14px
);

@each $el, $size in $sizeMap {
  #{$el} {
    font-size: $size;
  }
}
  • 编译结果
css
h1 {
  font-size: 20px;
}
h2 {
  font-size: 16px;
}
h3 {
  font-size: 14px;
}
  • 甚至可以用来解构
scss
$statusList:
  (text, text, "#333"), (button, pointer, "#ccc"), (div, move, "#0000");

@each $el, $pointer, $color in $statusList {
  .is-#{$el} {
    cursor: $pointer;
    color: $color;
  }
}
  • 编译结果
css
.is-text {
  cursor: text;
  color: "#333";
}
.is-button {
  cursor: pointer;
  color: "#ccc";
}
.is-div {
  cursor: move;
  color: "#0000";
}

@for

  • 注意

注意

SASS中的索引从1开始而不是0

SASS中的@for同样可以用来迭代,但它只能限制在一定的范围内,通常用来重复生成相同或者类似的样式,其公式有如下两种:

  1. @for <variable> from <expression> to <expression>,不包含最后一个值,类似于[)

  2. @for <variable> from <expression> through <expression>,包含最后一个值,类似于[]

  • 示例如下:
scss
// 不包含3
@for $i from 1 to 3 {
  .item-#{$i} {
    background-color: #58a;
    font-size: 12px * $i;
  }
}
  • 编译结果
css
.item-1 {
  background-color: #58a;
  font-size: 12px;
}
.item-2 {
  background-color: #58a;
  font-size: 24px;
}

@mixin 和 @include (用的最多)

SASS中的@mixin@include经常配对使用的,@mixin负责定义,@include负责引用。

@mixin 一般是用来定义一些经常会用到的代码,例如:ellipsisclearfix等。

可以把mixin 理解为函数关键字, include理解为函数调用

  • 代码如下:
scss
@mixin ellipsis {
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
}

@mixin clearfix {
  &::before,
  &::after {
    display: table;
    content: "";
  }
  &::after {
    clear: both;
  }
}
  • @mixin 也可以用来接收参数,甚至参数还可以使用默认值,当给参数定义默认值时,表示此参数为可选参数:
scss
// PC端版心mixin
@mixin pc-center($margin: 0, $width: 1200px) {
  margin: $margin auto;
  width: $width;
}

// 使用参数默认值
.box1 {
  @include pc-center;
}
// 自定义参数
.box2 {
  @include pc-center(10px, 1000px);
}
// 显示传值:显示给$width传递值,而$margin依旧使用参数默认值
.box3 {
  @include pc-center($width: 1000px);
}
  • @mixin中,也可以接收外部的内容,用@content来表示,例如:
scss
@mixin btn-hover {
  :not(.is-disabled):hover {
    @content;
  }
}

.button {
  @include btn-hover {
    border-width: 2px;
  }
}
  • 编译结果
css
.button :not(.is-disabled):hover {
  border-width: 2px;
}

@extend

个人不推荐使用

@function

SASS中的@function允许我们在值的基础上进行复杂的计算,其格式为@function <name>(<arguments...>) { ... }

scss
@function pow($base, $exponent) {
  $result: 1;
  @for $_ from 1 through $exponent {
    $result: $result * $base;
  }
  @return $result;
}

.sidebar {
  float: left;
  margin-left: pow(4, 3) * 1px; // 64px
}
  • mixin类似,@function也支持参数默认值以及参数收缩,例如:
scss
@function sum($numbers...) {
  $result: 0;
  @each $number in $numbers {
    $result: $result + $number;
  }
  @return $result;
}

.sidebar {
  float: left;
  width: sum(10px, 20px, 30px); // 60px
}

@use

SASS中的@use可以加载其他scss样式表中的mixinsfucntionsvariables,同时可以对加载的模块做一些其他额外的事情。

scss
// dark.scss文件
div {
  background-color: #333;
  color: #fff;
}

// 此处的use仅仅只是把`dark.scss`中的代码合并到当前样式表中,和`@import`的作用一样。
@use "dark";
.box {
  background-color: #58a;
}
  • 编译结果
scss
div {
  background-color: #333;
  color: #fff;
}
.box {
  background-color: #58a;
}
  • @use可以在引入的时候可以做一些额外的事情,例如使用自定义命名空间:
scss
// mixins.scss
@mixin ellipsis {
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
}

// index.scss
@use "mixins.scss" as mix // 默认的命名空间为mixins
  .box {
  @include mix.ellipsis;
}
  • @use也可以对加载的模块进行配置,例如:
scss
// mixins.scss
$defaultLine: 2;
@mixin multline-ellipsis($line: $defaultLine) {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: $line;
  text-overflow: ellipsis;
  overflow: hidden;
}

// index.scss
@use "mixins.scss" as mix with (
  $defaultLine: 3
);
.box {
  @include mix.multline-ellipsis;
}
  • 编译结果为
css
.box {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  text-overflow: ellipsis;
  overflow: hidden;
}