scss快速入门

栏目: CSS · 发布时间: 5年前

内容简介:SCSS 是 Sass 3 引入新的语法,其语法完全兼容 CSS3,并且继承了 Sass 的强大功能。也就是说,任何标准的 CSS3 样式表都是具有相同语义的有效的 SCSS 文件,官方解释。传统的css文件缺失变量等概念,导致需要书写的重复的代码很多。我写JS的习惯是遇见重复的代码就要思考是否可以抽出来写成一个可复用的方法,但css中不存在变量函数等概念,这时我发现的一个css的预编译利器——scss。scss具有简单易上手等特点,下面开始编写第一个scss文件。

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

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

scss具有简单易上手等特点,下面开始编写第一个scss文件。

准备工作

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

scss需要经过编译为css才能被浏览器识别,我这里只做一个小demo所以不上vue-cli,直接使用webpack进行编译。

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

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

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

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文件,接着在入口文件中引入。

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

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

正式开始

1.使用变量

SCSS中的变量以&开头。

&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还有很多功能,各位小伙伴可以先将目前的知识运用熟练再去学习也不迟。


以上所述就是小编给大家介绍的《scss快速入门》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Pragmatic Programmer

The Pragmatic Programmer

Andrew Hunt、David Thomas / Addison-Wesley Professional / 1999-10-30 / USD 49.99

本书直击编程陈地,穿过了软件开发中日益增长的规范和技术藩篱,对核心过程进行了审视――即根据需求,创建用户乐于接受的、可工作和易维护的代码。本书包含的内容从个人责任到职业发展,直至保持代码灵活和易于改编重用的架构技术。从本书中将学到防止软件变质、消除复制知识的陷阱、编写灵活、动态和易适应的代码、避免出现相同的设计、用契约、断言和异常对代码进行防护等内容。一起来看看 《The Pragmatic Programmer》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

随机密码生成器
随机密码生成器

多种字符组合密码

html转js在线工具
html转js在线工具

html转js在线工具