一看就会的SCSS

1,169 阅读5分钟

1.前言

ScssSass3 引入的新的语法,其语法完全兼容css3,并且继承了Sass的强大功能。SassScss其实是同一种东西。

Sass是一款强化CSS的辅助工具,它在CSS语法的基础上增加了变量(variables)、嵌套(nested rules)、混合(mixins)、导入(inline imports)等高级功能,这些拓展令CSS更加强大与优雅。使用Sass有助于更好地组织管理样式文件,以及更高效地开发项目。

2.SCSS基础

2.1嵌套选择器

编译前

body {
    background: #FFF;
    p{
        color: #000;
    }
}

编译为css

body {
  background: #FFF;
}
body p {
  color: #000;
}

2.2 &符号

编译前

// &符可以引用父级选择器
li {
    background: #FFF;
    a {
      color:#ff7788;
    }
    &::hover {
        background: #000;
    }
}
.card-item {
  width: 350px;
  height: 200px;
  &-img {
    width: 100%;
    height: 100%;
    object-fit: contain;
  }
}

编译为css

li {
  background: #FFF;
}

li a {
  color: #ff7788;
}

li::hover {
  background: #000;
}

.card-item {
  width: 350px;
  height: 200px;
}

.card-item-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

2.3 嵌套属性

比如字体有font-size,font-weight,font-family等多个属性,但每个属性前面都有个font,那么我们可以用嵌套属性来简写, 此方法使用使用较少

编译前

body {
    font: { //注意font后面一定要接 : ,不然会被认为是一个类名
        size:16px;
        weight:700;
        family:'宋体'
    }
}

编译为css

body {
  font-size: 16px;
  font-weight: 700;
  font-family: '宋体';
}

2.4 变量

编译前

$width: 5rem;
.main {
   width: $width;
}

编译为css

.main {
   width: 5rem;
}

2.5 @mixin混合

@mixin 可以将重复的代码提取出来,然后谁要用就 @include 引入

@mixin box {
    background: #ffff00;
    border:1px solid #ffff00;
    color:blue;
}
.bigBox {
    @include box;
    height:200px;
    width:200px;
}
.smallBox {
    @include box;
    height:50px;
    width:50px
}

编译为css

.bigBox {
  background: #ffff00;
  border: 1px solid #ffff00;
  color: blue;
  height: 200px;
  width: 200px;
}

.smallBox {
  background: #ffff00;
  border: 1px solid #ffff00;
  color: blue;
  height: 50px;
  width: 50px;
}

2.6 @extend

在写网页时常常遇到这种情况:一个元素使用的样式与另一个元素完全相同,但又添加了额外的样式。通常会在HTML中给元素定义两个class,一个通用样式,一个特殊样式。假设现在要设计一个普通错误样式与一个严重错误样式,一般会这样写:

<div class="error seriousError">
  Oh no! You've been hacked!
</div>

样式如下

.error {
  border: 1px #f00;
  background-color: #fdd;
}
.seriousError {
  border-width: 3px;
}

麻烦的是,这样做必须时刻记住使用 .seriousError 时需要参考 .error 的样式,带来了很多不便:比如加重维护负担,导致 bug,或者给 HTML 添加无语意的样式。

使用 @extend 可以避免上述情况,告诉 Sass 将一个选择器下的所有样式继承给另一个选择器。

.error {
  border: 1px #f00;
  background-color: #fdd;
}
.seriousError {
  @extend .error;
  border-width: 3px;
}

上面代码的意思是将 .error 下的所有样式继承给 .seriousErrorborder-width: 3px; 是单独给 .seriousError 设定特殊样式,这样,使用 .seriousError 的地方可以不再使用 .error

编译后

.error, .seriousError {
  border: 1px #f00;
  background-color: #fdd; 
}
.seriousError {
  border-width: 3px; 
}

再来一个例子:

编译前

.error {
  border: 1px #f00;
  background-color: #fdd;
}
.seriousError {
  @extend .error;
  border-width: 3px;
}
.criticalError {
  @extend .seriousError;
  position: fixed;
  top: 10%;
  bottom: 10%;
  left: 10%;
  right: 10%;
}

编译后

.error, .seriousError, .criticalError {
  border: 1px #f00;
  background-color: #fdd; 
}

.seriousError, .criticalError {
  border-width: 3px;
}

.criticalError {
  position: fixed;
  top: 10%;
  bottom: 10%;
  left: 10%;
  right: 10%;
}

继承这个方法会将共同的css写在一起,减少了代码量

2.7 @function

这个方法提供了在scss中计算属性的功能

@function r($size) {
  @return $size / 144 * 1rem;
}
// 使用
p {
  width: r(750);
}

编译后 (以html标签font-size: 150px 为例)

p {
  width: 5rem;
}

2.8 控制指令

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

编译后

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;
  }
}

编译为

p {
  color: green; 
}
2.8.2 @for

@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 $i from 1 through 3 {
  .item-#{$i} { width: 2rem * $i; }
}

编译为

.item-1 {
  width: 2rem;
}
.item-2 {
  width: 4rem;
}
.item-3 {
  width: 6rem; 
}
2.8.3 @each

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

@each 将变量 $var 作用于值列表中的每一个项目,然后输出结果,例如:

@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.8.4 @while

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

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

编译后

.item-6 {
  width: 12rem; 
}

.item-4 {
  width: 8rem;
}

.item-2 {
  width: 4rem;
}

2.9 文件导入@import

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

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

@import './style/default.scss';

p {
  font-size: 16px;
}

3.小结

变量是sass提供的最基本的工具。通过变量可以让独立的css值变得可重用,无论是在一条单独的规则范围内还是在整个样式表中。同样基础的是sass的嵌套机制。嵌套允许css规则内嵌套css规则,减少重复编写常用的选择器,同时让样式表的结构一眼望去更加清晰。sass同时提供了特殊的父选择器标识符&,通过它可以构造出更高效的嵌套。

你也已经学到了sass的另一个重要特性,样式导入。通过样式导入可以把分散在多个sass文件中的内容合并生成到一个css文件,避免了项目中有大量的css文件通过原生的css @import带来的性能问题。通过嵌套导入和默认变量值,导入可以构建更强有力的、可定制的样式。混合器允许用户编写语义化样式的同时避免视觉层面上样式的重复。你不仅学到了如何使用混合器减少重复,同时学习到了如何使用混合器让你的css变得更加可维护和语义化。继承允许你声明类之间语义化的关系,通过这些关系可以保持你的css的整洁和可维护性。

参考文档: Sass 中文网 Scss语法 Sass快速入门