一、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-size: 18px;
color: red;
}
index.scss文件
@import "common.scss";
.box {
background: $bgcolor;
}
编译结果
.box {
background: red;
}
common-box {
font-size: 18px;
color: red;
}
如果引入了两次common.scss文件编译结果为
.box {
background: red;
}
common-box {
font-size: 18px;
color: red;
}
common-box {
font-size: 18px;
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) ;
}
编译结果
实现效果