Sass知识点

222 阅读5分钟

一、scss变量

1、变量类型
    命名规则
-   以美元符号 `$` 开头,后面跟变量名;且必须先定义,后使用
-   变量名不能以数字开头,可包含字母、数字、下划线、横线(连接符)
-   通过连接符 `-` 与下划线 `_` 定义的同名变量为同一变量

    数字   $customZIndex:10;
    字符串 $customFontSize:12px;
    颜色   $customColor:#F00;
    布尔   $customBoolean: true;
    空值   $customNull: null;
    数组   $customPadding: 6px 10px 6px 10px;
    map    $customMap: (
                '90': 0.9,
                '60 ': 0.6
           );
2、!global、!default
$customColor:#F00;//全局变量
div {
    $customFontSize:12px !global;//全局变量
    $customWidth:100px;//局部变量
    
    $customHeight:100px;
    $customHeight:200px !default;//在这个定义之前有被定义时,不会使用这个新定义的值
    
    font-size:$customFontSize;
    color: $customColor;
    width:$customWidth;
    height:$customHeight;
}
//编译结果
div { 
    font-size: 12px;
    color: #F00;
    width: 100px;
    height: 100px;
}
3、插值语句 #{} 和模板字符串很像 可以在选择器、属性名、注释中使用
$fontStyle:italic;
$lineHeight: 30px;
$fontSize:12px;
p {
    font: $fontStyle #{$fontSize}/#{$lineHeight} Arial Helvetica, sans-serif;
}
//编译结果
p {
    font: italic 12px / 30px Arial Helvetica, sans-serif;
}

注:css变量

//定义
:root {
  --bg-color:#E2E9F4;
}
//使用
.ds-main{
    background-color: var(--bg-color);
}
//自定义修改变量
const el = document.documentElement;
el.style.setProperty("--bg-color", "#000");

二、条件语句if

语法:
@if ... {} @else if ... {} @else {}

$theme:3;
.p {
  @if $theme >= 5 {
    color: red;
  }
  @else {
    color: blue;
  }
}
//编译结果
.p {
  color: blue;
}

三、循环语句

语法:
1、@each $i in $list | @each $key,$value in $map

$marginKey:20, 25, 30, 35;
@each $i in $marginKey {
  .ml-#{$i}{
    margin-left: $i * 1px;
  }
}
//编译结果
.ml-20 { margin-left: 20px; }  
.ml-25 { margin-left: 25px; }  
.ml-30 { margin-left: 30px; }  
.ml-35 { margin-left: 35px; }
//遍历map例子看 四、map

2、@for $var from start through end
或者 @for $var from start to end
区别:through包含结束值,to不包含结束值

through
@for $i from 1 through 5 {
  .ml-#{$i}{
    margin-left: $i * 1px;
  }
}
//编译结果
.ml-1 { margin-left: 1px; }
.ml-2 { margin-left: 2px; }
.ml-3 { margin-left: 3px; }
.ml-4 { margin-left: 4px; }
.ml-5 { margin-left: 5px; }

to
@for $i from 1 to 5 {
  .ml-#{$i}{
    margin-left: $i * 1px;
  }
}
//编译结果
.ml-1 { margin-left: 1px; }
.ml-2 { margin-left: 2px; }
.ml-3 { margin-left: 3px; }
.ml-4 { margin-left: 4px; }

3、@while

$num: 12;
@while $num < 18 {
  .fs-#{$num} {
    font-size: #{$num}px;
  }
  $num: $num + 2;
}
//编译结果
.fs-12 { font-size: 12px; }
.fs-14 { font-size: 14px; }
.fs-16 { font-size: 16px; }

四、map

1、遍历

$primaryColor:#409eff;
$background_color: (
    '90': 0.9,
    '60 ': 0.6,
    '30': 0.3
);

@each $key, $value in $background_color {
    .mini-theme-color-opacity-#{$key} {
        background: rgba($primaryColor, $value);
    }
}
编译结果
.mini-theme-color-opacity-90 {
  background: rgba(#409eff, 0.9);
}
.mini-theme-color-opacity-60 {
  background: rgba(#409eff, 0.6);
}
.mini-theme-color-opacity-30 {
  background: rgba(#409eff, 0.3);
}

2、map-values() 用法很像Object.values()

$customTransition:(
  'transform':transform 400ms ease,
  'opacity':opacity 400ms ease
);
.box {
  transition: map-values($customTransition);
}
编译结果
div{
    transition: transform 400ms ease, opacity 400ms ease;
}

3、map-keys() 用法很像Object.keys()

$customPlatform:(
    'wechat':'#666',
    'h5':'#999'
);
@each $name in map-keys($customPlatform){
    .btn-#{$name}{
        color:map-get($customPlatform$name);//maps取值
    }
}
编译结果
.btn-wechat {
    color: #666;
}
.btn-h5 {
    color: #999;
}

4、map-has-key(maps,key)、map-merge(map1,map2)

// map-has-key 判断 map 是否有对应的 key,存在返回 true,否则返回 false。
$font-sizes: ("small": 12px, "normal": 18px, "large": 24px);
map-has-key($font-sizes, "big");
//返回false

//map-merge(map1,map2) 合并两个 map 形成一个新的 map 类型
$customPlatform1:(
  'wechat':#666,
  'h5':#999
);
$customPlatform2:(
  'facebook':#333,
);
$customPlatform:(
  map-merge($customPlatform1,$customPlatform2)
  //返回 'wechat':#666,'h5':#999,'facebook':#333
);
@each $name in map-keys($customPlatform){
  .btn-#{$name}{
    color:map-get($customPlatform,$name);
  }
}
编译结果
.btn-wechat {
    color: #666;
}
.btn-h5 {
    color: #999;
}
.btn-facebook {
    color: #333;
}

//map-remove(map,key1,key2,...) 移除key值
$customPlatform1:(
  'wechat':#666,
  'h5':#999,
  'facebook':#333
);
$customPlatform:(
  map-remove($customPlatform1,'wechat','facebook')
  //返回'h5':#999
);
@each $name in map-keys($customPlatform){
  .btn-#{$name}{
    color:map-get($customPlatform,$name);
  }
}
编译结果
.btn-h5 {
    color: #999;
}

五、@function函数

一、内置函数

二、自定义函数

//例一 
@function shade($color, $percent:20%) {//可设置默认值,没有默认值且不传值时编译报错
  @return mix($color, #000, $percent);
}
.box {
  background-color: shade(#fff, 80%);
}
//mix是scss自定义函数,返回第一个颜色值的$percent混合第二个颜色值,即#fff占80%,#000占20%
//编译结果
.box {
    background-color: #cccccc;
}

//例二 可变参数 很像js的rest参数
@function sum($numbers...) {
    $sum: 0;
    @each $number in $numbers {
        $sum: $sum + $number;
    }
    @return $sum;
}

$widths: 50px, 30px, 100px;
.box {
    width: sum($widths...);
}
//编译结果
.box {
    width: 180px;
}

六、@mixin 混入

@mixin 指令允许我们定义一个可以在整个样式表中重复使用的样式。
@include 指令可以将混入(mixin)引入到文档中。

@mixin text {
    font-size: 25px;
    background: red;
    border: 1px solid blue;
}
.box {
    color: #fff;
    @include text;
}
//编译结果
.box {
    color: #fff;
    font-size: 25px;
    background: red;
    border: 1px solid blue;
}

mixin传参

//单个参数
@mixin text($bgcolor) {
  font-size: 25px;
  background: $bgcolor;
  border: 1px solid blue;
}
.box {
  @include text(red);
}
//编译结果
.box {
  font-size: 25px;
  background: red;
  border: 1px solid blue;
}
//多个参数
@mixin boxPadding($top:0,$bottom:0,$left:0,$right:0) {
  padding-top: $top;
  padding-bottom: $bottom;
  padding-left: $left;
  padding-right:$right;
}
.box {
  @include boxPadding;
}
.box1 {
  @include boxPadding(20px,20px);
}
.box2 {
  @include boxPadding($left:20px,$right:20px);
}
//编译结果
.box {
    padding-top: 0;
    padding-bottom: 0;
    padding-left: 0;
    padding-right: 0;
}
.box1 {
    padding-top: 20px;
    padding-bottom: 20px;
    padding-left: 0;
    padding-right: 0;
}
.box2 {
    padding-top: 0;
    padding-bottom: 0;
    padding-left: 20px;
    padding-right: 20px;
}
//剩余参数
@mixin linearGradient($colors...) {
  color:#fff;
  background-image: linear-gradient(to right, $colors);
}
.box {
  @include linearGradient(red,yellow,blue,green);
  color:#000;//这两个语句调换则box文字呈现白色,在后面的语句会覆盖前面的样式。
}
//编译结果
.box {
    color:#fff;//不生效
    background-image: linear-gradient(to right, red, yellow, blue, green);
    color: #000;
}
//@content 类似插槽
@mixin card-box {
    border: 1px solid red;
    padding: 20px;
    @content;
}
.box {
    @include card-box {
        background-color: #f0f0f0;
        border-color: #999;
    }
}
//编译结果
.box {
    border: 1px solid red;
    padding: 20px;
    background-color: #f0f0f0;
    border-color: #999;
}

七、@import导入

被导入的文件中所包含的变量或者混合mixin都可以在导入的文件中使用;
被导入的文件将合并编译到同一个 css 文件中;
可导入多个文件,语法@import "文件1", "文件2";

common.scss文件

$bgcolor:red;
common-box { 
  font-size18px;  
  color: red;  
}

index.scss文件

@import "common.scss";
.box {
  background: $bgcolor;
}

编译结果

.box {
  background: red;
}
common-box {
  font-size18px;  
  color: red;  
}

如果引入了两次common.scss文件编译结果为

.box {
  background: red;
}
common-box {  
  font-size18px;  
  color: red;  
}
common-box {  
  font-size18px;  
  color: red;  
}

八、@Partials局部文件

假设有一个只有变量的test.scss文件,将会被编译成一个空的test.css文件。
如果不希望将一个 Sass 的代码文件编译到一个 CSS 文件,可以在文件名的开头添加一个下划线。这将告诉 Sass 不要将其编译到 CSS 文件、专门用于被其他的 scss文件 @import进行使用的。
注:不能将带下划线与不带下划线的同名文件放置在同一个目录下,否则带下划线的文件将会被忽略。

_common.scss文件

$bgcolor:red;

index.scss文件

@import "common.scss";
.box {
  background: $bgcolor;
}

index.scss编译结果

.box {
  background: red;
}

总结:@function用来计算靠return出一个值,@mixin用来封装样式,@import用来抽离一个模块。

九、@extend继承

继承已经有的样式

.commonContent{
    background-color: red;
    padding:20px;
}
.box{
    @extend .commonContent;
    border-radius: 10px;
}
.box1{
    @extend .commonContent;
    border-radius: 20px;
}
//编译结果
.commonContent,.box,.box1 {
    background-color: red;
    padding:20px;
}
.box{
    border-radius: 10px;
}
.box1{
    border-radius: 20px;
}

十、@use

用来代替@import

@import的缺点
1、导入多个文件时不容易找到变量或混入。
2、多处导入,存在样式重复加载。
3、两个 mixin 文件中有相同的名称,会导致非预期的结果。
4、使所有变量、mixin 和函数都可以全局访问,没有私有函数的概念。

1、默认命名空间 src/assets/styles/common.scss

$color: #fff;
@mixin bg-white {
    background: red;
}

index.scss

@use "src/assets/styles/common";//默认命名空间common

.box{
    color:common.$color;
    @include common.bg-white;
}
//编译结果
.box {
    color: #fff;
    background: red;
}

2、命名空间
src/assets/styles/common.scss

$color: #fff;
@mixin bg-white {
    background: red;
}

index.scss

@use "src/assets/styles/common" as box;

.box{
    color:box.$color;
    @include box.bg-white;
}
//编译结果
.box {
    color: #fff;
    background: red;
}

3、全局命名空间
src/assets/styles/common.scss

$color: #fff;
@mixin bg-white {
    background: red;
}

index.scss

@use "src/assets/styles/common" as *;

.box{
    color:$color;
    @include bg-white;
}
//编译结果
.box {
    color: #fff;
    background: red;
}

4、私有模块 src/assets/styles/common.scss

$-color: #fff;
@mixin -bg-white {
    background: red;
}

index.scss

@use "src/assets/styles/common" as *;

.box{
    color:$color;
    @include bg-white;
}
//编译结果报错
Error: Undefined variable.
     ╷
  77 │   color:$color;
     │         ^^^^^^
     ╵
    src\views\example\TsForm.vue 77:9  root stylesheet
Error: Undefined mixin.
     ╷
  78 │   @include bg-white;
     │   ^^^^^^^^^^^^^^^^^
     ╵
    src\views\example\TsForm.vue 78:3  root stylesheet

5、修改默认值
test.scss文件

$color: red !default;
.box {
  background: $color;
}

index.vue文件

<template>
    <div class="box" style="width: 100px;height:100px"></div>
</template>
<style lang="scss" scoped>
    //with()语法修改默认值
    @use './test' with($color: blue);
    
    //编译结果
    .box {
        background: blue;
    }
</style>

缺陷
box.scss文件

$c-red: red;
.box {
    width:100px;
    height: 100px;
    background-color: $c-red;  
}

box1.scss文件

$c-blue: blue;
.box1{
    width:100px;
    height: 100px;
    background-color: $c-blue;
}

index.scss文件

@use "box";
@use "box1";

index.vue文件

@use 'common/index';
.content{
    width: 200px;
    height: 200px;
    background: index.$c-red;
}
//编译报错,无法使用box和box1中的变量,注释掉content类名后编译结果
.box {
    width:100px;
    height: 100px;
    background-color: red;  
}
.box1{
    width:100px;
    height: 100px;
    background-color: blue;
}

解决方式,使用@forward

十一、@forward

@forward语句可以引入另一个模块的所有变量、mixins和函数,将它们直接作为当前模块的API暴露出去,类似于export。

index.scss文件

@forward "box";
@forward "box1";

index.vue文件

@use 'common/index';
.content{
    width: 200px;
    height: 200px;
    background: index.$c-red;
}
//编译结果
.box {
    width:100px;
    height: 100px;
    background-color: red;  
}
.box1{
    width:100px;
    height: 100px;
    background-color: blue;
}
.content{
    width: 200px;
    height: 200px;
    background: red;
}

1、show/hide

index.scss文件

// 控制变量的显示和隐藏,多个变量用,隔开
@forward "box" show $c-red;
@forward "box1" hide $c-blue;

2、添加前缀

index.scss文件

@forward "box" as box-*; //使用box.scss中的变量需要加上前缀box- 如$box-c-red
@forward "box1" as box1-*; //使用box.scss中的变量需要加上前缀box1- 如$box1-c-blue

index.vue文件

@use 'common/index';
.content{
  width: 200px;
  height: 200px;
  background: index.$box-c-red;
}

十二、例

<div style="width:100vw;height:100vh;background: blue">
    <div class="layer1"></div>
</div>
@function getShadow($n){
  $shadows:'#{random(100)}vw #{random(100)}vh #fff';
  @for $i from 2 through $n {
    $shadows: '#{$shadows}, #{random(100)}vw #{random(100)}vh #fff';
  };
  @return unquote($shadows);
}

.layer1{
  $size:5px;
  position: fixed;
  width: $size;
  height: $size;
  border-radius: 50%;
  background: #f40;
  left: 0;
  top: 0;
  // box-shadow: 10vw 10vh #fff,20vw 20vh #fff ;
  box-shadow:  getShadow(100) ;
}

编译结果

image.png

实现效果

image.png