掌握SCSS高级用法

845 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情

前言

SCSS vs SASS

SASS(Syntactically Awesome Style Sheets),是一种预处理的脚本语法,SCSS是基于SASS的主要方法,建立在CSS语法上的一种特殊语法。学习成本相对较低。SCSS和SASS可以相互引用。

文章以下内容,主要介绍SCSS语法中的一些高级用法。

前置知识

如果你对SCSS中的变量声明或是嵌套结构还没有了解,请先转跳至SASS官网了解后阅读本文。

Chapter 1

本章主要介绍SCSS中公共样式定义的一些方式。CSS中最头疼的问题之一,我认为就是选择器结构的规划和定义。SCSS中使用公共样式定义结合嵌套,可以更好的解决结构化问题。

继承

@extend, 在使用的选择器中插入被继承的选择器样式。

.icon {...}

.error-icon {
  @extend .icon;
}

.success-icon {
  @extend .icon;
}

混入(Mixin)

@mixin, 定义可重复使用的样式片段,使用@include,可以将定义的Mixin导入。

@mixin icon-style {...}

.error-icon {
  @include icon-style;
}

.success-icon {
  @include icon-style;
}

在一个混入中也可以引入其他混入

@mixin special-icon {
  @include icon-style;
  @include special-style;
}

混入中传递变量。

// $[变量名]:[默认值]
@mixin icon($bg-color:grey) {
  background-color: $bg-color;
}

.success-icon {
  @include icon(green);
}

.error-icon {
  @include icon(red)
}

占位符

%placeholder,使用表现上是一个类选择器,但是不会在编译之后的css文件中输出。

%icon {...}

.success-icon {
  @extend %icon;
}

.error-icon {
  @extend %icon;
}

继承 vs 混入

到这边,你可能会有些疑问,恭喜,这说明你是在认真思考的。继承和混入表现上都是定义一段样式,并且可以重复使用,那么他们之间的区别究竟是什么呢?

首先,上文中提到了SCSS中的三种用法:继承混入占位符。我们先来讨论占位符。将他排除在其余两者之外。

我们可以看到,继承使用的时候,继承的对象可以是普通的类选择器,也可以是占位符。他们的区别在于转换为CSS之后的结果:

// scss 使用占位符及非占位符实现继承
// ---- start ----

// 使用占位符继承
%ph {
  background-color: red;
}

.ph-extend1 {
  @extend %ph;
  font-size: 12px;
}

.ph-extend2 {
  @extend %ph;
  font-size: 14px;
}

// 使用选择器继承
.parent {
  background-color: green;
}

.parent-extend1 {
  @extend .parent;
  font-size: 12px;
}

.parent-extend2 {
  @extend .parent;
  font-size: 14px;
}
// ---- end ----

// 处理后,转换成的css结果
// ---- start ----
// 使用占位符继承
.ph-extend1, .ph-extend2 {
  background-color: red;
}

.ph-extend1 {
  font-size: 12px;
}

.ph-extend2 {
  font-size: 14px;
}

// 使用选择器继承
.parent, .parent-extend1, .parent-extend2 {
  background-color: green;
}

.parent-extend1 {
  font-size: 12px;
}

.parent-extend2 {
  font-size: 14px;
}

// ---- end ----

以上代码可以很清楚的看出,使用选择器继承占位符继承的区别在于,编译成css只有是否会产生被继承的选择器。那么什么时候使用占位符也显而易见了,当我们的代码中没有计划使用或者从来没有使用过被继承的选择器,我们就可以使用占位符来定义需要重复使用的样式。

OK,我们已经讨论完了占位符,下面可以进入正题:继承混入之间的区别

还是和上面的方式一样,我们来举一个例子,并查看继承混入转换为CSS之后的样子:

// scss分别使用继承和混入
// ---- start ----

// 使用继承
%extend {
  background-color: red;
}

.extend1 {
  @extend %extend;
  font-size: 12px;
}

.extend2 {
  @extend %extend;
  font-size: 14px;
}

// 使用混入
@mixin mixin {
  background-color: green;
}

.mixin1 {
  @include mixin;
  font-size: 12px;
}

.mixin2 {
  @include mixin;
  font-size: 14px;
}
// ---- end ----

// 处理后,转换成的css结果
// ---- start ----
// 使用继承
.extend1, .extend2 {
  background-color: red;
}

.extend1 {
  font-size: 12px;
}

.extend2 {
  font-size: 14px;
}

// 使用混入
.mixin1 {
  background-color: green;
  font-size: 12px;
}

.mixin2 {
  background-color: green;
  font-size: 14px;
}
// ---- end ----

可以看出最大的区别是,使用继承会将公共的样式部分同时声明,而使用混入会将公共样式分别插入使用混入的地方。既然如此,很容易就可以想到:过度使用混入会使得编译之后CSS文件体积变大

如何选择?

当然一切选择,都取决于实际的使用场景。但是一般而言,如果是静态样式声明(没有使用变量的情况),推荐使用继承,这样可以避免一些不必要的冗余样式代码。当然使用占位符的方式更好,如非使用到了被继承的选择器。如果用到了动态样式声明,选择混入,这样可以避免重复声明。

Chapter 2

本章介绍SCSS中的控制语句:选择循环遍历

选择

使用@if@else if@else,控制声明的样式块选择器

@mixin border-color($color, $direction) {
  @if $direction == up {
    border-bottom-color: $color;
  } @else if $direction == right {
    border-left-color: $color;
  } @else if $direction == down {
    border-top-color: $color;
  } @else if $direction == left {
    border-left-color: $color;
  } @else {
    @error "Unknown direction #{$direction}.";
  }
}
  
.border-red-left {
  @include border-color(red, left);
}

循环

使用@for关键字,进行循环操作,常见用法如相似度很高的同类选择器的定义。

@for有以下两种使用方式:

// @for $var from <start> through <end>
// @for $var from <start> to <end>
@for $i from 1 through 3 {
  .item-a-#{$i} {
    width: $i * 2px;
  }
}
// result: .item-a-1 ... .item-a-3

@for $i from 1 to 3 {
  .item-b-#{$i} {
    width: $i * 2px;
  }
}
// result: .item-b-1 ... .item-b-2

from <start> through <end>左右闭区间。即,左右边界均包含。

from <start> to <end>左闭右开区间。即,只包含左边界,不包含右边界。

<start><end>均为正整数

使用@while关键字也可以实现循环操作,但是我们平时一般很少,这里简单带过一下。

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

代码来自官方文档

遍历

使用@each关键字对列表进行遍历操作。使用方式如下:

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

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

代码来自官方文档

Chapter 3

本章主要介绍常用的内置方法

内置方法API推荐查看这篇博客,写的非常完整,而且是中文的,毫无阅读障碍。可以通篇过一遍,留下印象,之后遇到需要使用的情况,再当做工具网站来查找。

以下内容总结了常用的一些内容方法,以及使用方式。

开发过程当中我们可能会面临,设计稿中,UI使用透明度来设置颜色的情况,或者需要我们来调节灰度等属性,那么可以使用以下方法:

// rgba颜色方法封装
rgba(#800, .2); // 颜色#800再加上.2的透明度
// 提高亮度
lighten(#800, 20%); 
// 降低亮度
darken(#800, 20%);

其次还有饱和度透明度的一些内置方法,这里就不展开了。工程的话用到的机会不多,但是结合循环条件等控制语句,再加上灰度饱和度的属性控制可以实现一些高级炫酷的样式效果,此处按下不表,以后如果有机会再单独拿出来分享。

还有一些比如列表操作appendindexlength数值操作maxminMap操作map-getmap-has-key, 等等。这些方法相信有一定编程经验的同学,一眼就知道是干什么的了,建议还是扫一遍上面推荐的博客。

总结

本篇主要介绍了SCSS中的一些高级用法:继承混入控制语句等内容。在我们开发过程中我们可以运用这些高级用法,更好地组织我们的样式代码,降低后期的维护成本,也可以实现一些高级样式。重点篇幅着重在介绍继承混入以及他们的区别,这也是被很多小伙伴忽视或者没有彻底理解的部分。

qb abg fhpphzo gb guvf qnex jbeyq.

tip:13

CUL. :)

附录

参考资料