scss快速入门

在使用scss以前,咱们要知道Sass、Scss有什么不一样?

SCSS 是 Sass 3 引入新的语法,其语法彻底兼容 CSS3,而且继承了 Sass 的强大功能。也就是说,任何标准的 CSS3 样式表都是具备相同语义的有效的 SCSS 文件,官方解释css

传统的css文件缺失变量等概念,致使须要书写的重复的代码不少。我写JS的习惯是碰见重复的代码就要思考是否能够抽出来写成一个可复用的方法,但css中不存在变量函数等概念,这时我发现的一个css的预编译利器——scss。html

scss具备简单易上手等特色,下面开始编写第一个scss文件。前端

准备工做

写在最前面:有小伙伴可能不太会部署前端环境,这里我将代码上传到github中,有须要的小伙伴能够把代码下载下来对照着看SCSS代码与编译后的CSS代码。vue

scss须要通过编译为css才能被浏览器识别,我这里只作一个小demo因此不上vue-cli,直接使用webpack进行编译。node

首先安装css-loader、style-loader、node-sass、sass-loader。webpack

npm install css-loader style-loader --save-dev
npm install node-sass sass-loader --save-dev
复制代码

而后在webpack.config.js配置文件中添加对应的loader,完整的配置图以下。git

const path = require("path");
const {VueLoaderPlugin} = require('vue-loader');
module.exports = {
    entry: './webapp/App.js',
    output: {
        filename: 'App.js',
        path: path.resolve(__dirname, './dist')
    },
	module: {
		rules: [
            {
                test: /\.scss/,
                use: ['style-loader', 'css-loader','sass-loader']
            },
			{
				test: /\.vue$/,
				use: 'vue-loader'
			}
		]
	},
	plugins: [
		new VueLoaderPlugin()
	],
	mode: "production"
}

复制代码

建立一个App.scss文件,接着在入口文件中引入。github

import './App.scss';
复制代码

后面咱们将在App.scss中编写scss代码。web

正式开始

1.使用变量

SCSS中的变量以$开头。vue-cli

$border-color:#aaa; //声明变量
.container {
$border-width:1px;
    border:$border-width solid $border-color; //使用变量
}
复制代码

上述例子中定义了两个变量,其中$border-color在大括号以外称为全局变量,顾名思义任何地方均可以使用,$border-width是在.container以内声明的,是一个局部变量,只有.container内部才能使用。

编译后的CSS

.container {
    border:1px solid #aaa; //使用变量
}
复制代码

咱们能够把SCSS看作一个模板引擎,编译的过程当中用变量的值去替代变量所占据的位置。

tips:SCSS中变量名使用中划线或下划线都是指向同一变量的,上文中定义了一个变量$border-color,这时再定义一个变量$border_color:#ccc,他们指向同一个变量,.container的值会被第二次定义的变量覆盖。

$border-color:#aaa; //声明变量
$border_color:#ccc;
.container {
    $border-width:1px;
    border:$border-width solid $border-color; //使用变量
}
编译后的CSS
.container {
    border:1px solid #ccc; //使用变量
}
复制代码

这个例子中咱们要知道

(1)变量名使用中划线或下划线都是指向同一变量的。

(2)后定义的变量声明会被忽略,但赋值会被执行,这一点和ES5中var声明变量是同样的。

2.嵌套规则

咱们先来看一个例子。

/*css*/
.container ul {
    border:1px solid #aaa;
    list-style:none;
}

.container ul:after {
    display:block;
    content:"";
    clear:both;
}

.container ul li {
    float:left;
}

.container ul li>a {
    display:inline-block;
    padding:6px 12px;
}
复制代码

这是一个让列表元素横向排列的例子,咱们在这个例子中写了不少重复的代码,.container写了不少遍,下面我将用SCSS简写上面的例子。

2.1嵌套选择器

/*scss*/
.container ul {
    border:1px solid #aaa;
    list-style:none;
    
    li {
        float:left;
    }
    
    li>a {
        display:inline-block;
        padding:6px 12px;
    }
}

.container ul:after {
    display:block;
    content:"";
    clear:both;
}
复制代码

这里咱们能够将公共的父元素提取出来。

2.2嵌套中的父级选择器

SCSS提供了一个选择器能够选中当前元素的父元素,使用&表示,下面用父级选择器继续简化代码。

/*scss*/
.container ul {
    border:1px solid #aaa;
    list-style:none;
    
    li {
        float:left;
    }
    
    li>a {
        display:inline-block;
        padding:6px 12px;
    }
    
    &:after {
        display:block;
        content:"";
        clear:both;
    }
}
复制代码

父级选择器中须要注意,只能在嵌套内部使用父级选择器,不然SCSS找不到父级元素会直接报错。 在各类伪类选择器中,父级选择器是十分经常使用的。

2.3嵌套组合选择器

在嵌套规则中能够写任何css代码,包括群组选择器(,),子代选择器(>),同层相邻组合选择器(+)、同层全体组合选择器(~)等等,下面继续将自带选择器简化掉。

/*scss*/
.container ul {
    border:1px solid #aaa;
    list-style:none;
    
    li {
        float:left;
        
        >a {
            display:inline-block;
            padding:6px 12px;
        }
    }
    
    &:after {
        display:block;
        content:"";
        clear:both;
    }
}
复制代码

子代选择器能够写在外层选择器右边(以下述例子)也能够写在内层选择器左边(如上述例子)。

li >{ 
    a {
        display:inline-block;
        padding:6px 12px;
    }
}
复制代码

写在外层选择器右边时要特别注意,他会做用于全部嵌套的选择器上,尽可能不要采用这类写法,我认为扩展性不强,也容易出错。

2.4嵌套属性

先看一个例子

/*css*/
li {
    border:1px solid #aaa;
    border-left:0;
    border-right:0;
}
复制代码

这个例子中咱们只须要两条边框,使用SCSS重写一遍。

/*scss*/
li {
    border:1px solid #aaa {
        left:0;
        right:0;
    }
}
复制代码

scss识别一个属性以分号结尾时则判断为一个属性,以大括号结尾时则判断为一个嵌套属性,规则是将外部的属性以及内部的属性经过中划线链接起来造成一个新的属性。

3.导入SCSS文件

大型项目中css文件每每不止一个,css提供了@import命令在css内部引入另外一个css文件,浏览器只有在执行到@import语句后才会去加载对应的css文件,致使页面性能变差,故基本不使用。SCSS中的@import命令跟原生的不太同样,后续会讲解到。

3.1导入变量的优先级问题-变量默认值

/*App1.scss*/
$border-color:#aaa; //声明变量
@import App2.scss;  //引入另外一个SCSS文件
.container {
    border:1px solid $border-color; //使用变量
}
/*App2.scss*/
$border-color:#ccc; //声明变量

/*生成的css文件*/
.container {
    border:1px solid #ccc; //使用变量
}
复制代码

这可能并非咱们想要的,有时候咱们但愿引入的某些样式不更改原有的样式,这时咱们可使用变量默认值。

/*App1.scss*/
$border-color:#aaa; //声明变量
@import App2.scss;  //引入另外一个SCSS文件
.container {
    border:1px solid $border-color; //使用变量
}
/*App2.scss*/
$border-color:#ccc !default; //声明变量

/*生成的css文件*/
.container {
    border:1px solid #aaa; //使用变量
}
复制代码

导入的文件App2.scss只在文件中不存在$border-color时起做用,若App1.scss中已经存在了$border-color变量,则App2.scss中的$border-color不生效。

!default只能使用与变量中。

3.2嵌套导入

上一个例子中咱们是在全局中导入的App2.scss,如今咱们在为App2.scss添加一些内容,并在局部中导入。

/*App1.scss*/
$border-color:#aaa; //声明变量
.container {
    @import App2.scss;  //引入另外一个SCSS文件
    border:1px solid $border-color; //使用变量
}
/*App2.scss*/
$border-color:#ccc !default; //声明变量
p {
    margin:0;
}

/*生成的css文件*/
.container {
    border:1px solid #aaa; //使用变量
}
.container p {
    margin:0;
}
复制代码

能够看得出来,就是将App2.scss中的全部内容直接写入到App1.scss的.container选择器中。

3.3 使用原生@import

前面咱们说到基本不使用原生@import,但某些状况下咱们不得不使用原生@import时了,SCSS也为咱们处理了这种状况,直接导入css文件便可。

@import 'App.css';
复制代码

4.注释

SCSS中的注释有两种

(1)/*注释*/:这种注释会被保留到编译后的css文件中。

(2)//注释:这种注释不会被保留到编译后生成的css文件中。

5.混合器(函数)

5.1声明一个函数

使用@mixin指令声明一个函数,看一下本身的css文件,有重复的代码片断均可以考虑使用混合器将他们提取出来复用。

@mixin border-radius{
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    border-radius: 5px;
    color:red;
}
复制代码

混合器做用域内的属性都是return的值,除此以外,还能够为函数传参数。

@mixin get-border-radius($border-radius,$color){
    -moz-border-radius: $border-radius;
    -webkit-border-radius: $border-radius;
    border-radius: $border-radius;
    color:$color;
}
复制代码

也能够设置混合器的默认值。

@mixin get-border-radius($border-radius:5px,$color:red){
    -moz-border-radius: $border-radius;
    -webkit-border-radius: $border-radius;
    border-radius: $border-radius;
    color:$color;
}
复制代码

5.2使用函数

使用函数的关键字为@include

.container {
    border:1px solid #aaa;
    @include get-border-radius;         //不传参则为默认值5px
    @include get-border-radius(10px,blue);   //传参
}
/*多个参数时,传参指定参数的名字,能够不用考虑传入的顺序*/
.container {
    border:1px solid #aaa;
    @include get-border-radius;         //不传参则为默认值5px
    @include get-border-radius($color:blue,$border-radius:10px);   //传参
}
复制代码

咱们可能会想到,直接将混合器写成一个class不就好了,可是写成一个class的时候是须要在html文件中使用的,而使用混合器并不须要在html文件中使用class既可达到复用的效果。

tips:混合器中能够写一切scss代码。

6.继承

继承是面向对象语言的一大特色,能够大大下降代码量。

6.1定义被继承的样式

%border-style {
  border:1px solid #aaa;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  border-radius: 5px;
}
复制代码

使用%定义一个被继承的样式,相似静态语言中的抽象类,他自己不起做用,只用于被其余人继承。

6.2继承样式

经过关键字@extend便可完成继承。

.container {
	@extend %border-style;
}
复制代码

上述例子中看不出混合器与继承之间的区别,那么下一个例子能够看出继承与混合器之间的区别。

.container {
	@extend %border-style;
	color:red;
}
.container1 {   //继承另外一个选择器
	@extend .container;
}
复制代码

7.小结

经过本文的介绍,相信你们已经对SCSS有了必定的认知,可是光看是学不会的,我建议各位小伙伴要有强上的精神,先强行使用到目前正在作的项目中,熟悉一段时间,天然能够写出优质的SCSS代码。

8.其余

8.1操做符

SCSS提供了标准的算术运算符,例如+、-、*、/、%。

/*SCSS*/
width: 600px / 960px * 100%;
/*编译后的CSS*/
width: 62.5%;
复制代码

除此以外SCSS还有不少功能,各位小伙伴能够先将目前的知识运用熟练再去学习也不迟。

9.交流

若是这篇文章帮到你了,以为不错的话来点个Star吧。 github.com/lizijie123