Sass基础入门
Posted 川峰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sass基础入门相关的知识,希望对你有一定的参考价值。
目前公司多端项目开发中使用的 js/css文件结构如下:
如果你也是第一次接触这种,你会好奇的发现它的.css文件命名方式有点不同,要想搞清楚这个命名,主要了解两个东西,一个是 CSS Modules, 通过该链接我们了解到 CSS Modules
就是以模块化的方式来管理 CSS
,它可以避免 CSS
样式全局污染的问题,因为使用CSS Module
编译后的class
类名会变成一个唯一的字符串, 它是采用 css-loader
默认的哈希算法[hash:base64]
来生成的唯一值。另一个需要了解的就是 .scss
,它是什么后缀呢,搜索一下就知道它是 Sass 格式的后缀,本文主要记录一下Sass的入门知识。
文章目录
什么是 Sass?
- Sass 是一个稳定的、强大的、专业级的 CSS 扩展语言
- Sass 是基于 CSS 扩展出来的,是一个 CSS 预处理器
- Sass 在编译后会转换为 CSS 的,它只在编译时去做处理,而不是在运行时
Sass
的缩排语法,对于写惯css
前端的web
开发者来说很不直观,也不能将css
代码加入到Sass
里面,因此Sass
语法进行了改良,Sass 3
就变成了Scss(Sassy CSS)
。SCSS
是CSS
语法的扩展。即每一个有效的CSS
也是一个有效的SCSS
语句,与原来的语法兼容,只是用取代了原来的缩进。
因此我们有时看到的是
.sass
有时是.scss
, 其实它俩是一样的,只不过一个是SASS
的后缀, 一个是SCSS
的后缀,都是同一个东西,区别有点像iPhone和iPhone Plus。
为什么要使用 Sass?
主要是为了 提高开发效率 和 提高代码可维护性!在大型的 web 应用开发中我们一般会编写大量的样式代码,Sass 在 CSS 的基础上提供了变量、嵌套 (nesting)、混合 (mixins) 、函数、指令等功能,使得我们可以更高效地编写样式,同时你还可以像编写 JS 一样来灵活地控制你的样式代码,这给 CSS 的开发带来了极大的便利!
在前端项目中安装 Sass
首先要知道两个类库: node-sass
和 dart-sass
,这两个都是Sass
的实现 ,本身 Sass
是使用 Ruby
语言写的,但是它提供了很多接口以方便其他语言来集成和封装,node-sass
和 dart-sass
就是基于 LibSass
( Sass 的 C 版本) 封装而来的。
它们和 LibSass 的关系就是橘子和橘子汁的关系:
由于很少有人用dart
来开发前端项目,所以前端一般都是用 node-sass
这个库
安装 node-sass
一般使用 npm 或者 yarn 来安装:npm install node-sass
安装过程会去下载,如果下载失败,可能需要配置 npm 的源为淘宝镜像:
npm install -g mirror-config-china --registry=http://registry.npm.taobao.org
前端的项目是使用 Webpack 来构建,那么我们还需要使用 sass-loader
来编译项目中的 Sass ,所以我们需要在 Webpack 的配置中配置 sass-loader
,配置如下:
// webpack.config.js
module.exports =
...
module:
rules: [
test: /\\.scss$/,
use: [
loader: "style-loader" // 将 JS 字符串生成为 style 节点
,
loader: "css-loader" // 将 CSS 转化成 CommonJS 模块
,
loader: "sass-loader" // 将 Sass 编译成 CSS
]
]
;
执行如下命令安装 sass-loader :
npm install sass-loader --save-dev
总结:
Sass 嵌套
Sass使得你可以在父选择器的样式中直接编写子元素的样式,然后在一个子元素的样式中再去编写孙元素的样式,可以一层一层的嵌套着去写样式。
样式嵌套
用编写一个导航的样式来举例,假定我们的导航 nav 下面有 ul 标签,ul 标签下又有 li 标签,li 标签下呢又有 a 标签,下面我使用 Sass 来处理导航中的样式:
nav
width:200px;
background:white;
ul
width:100%;
background:red;
li
width:100%;
background:blue;
a
color:green;
font-size:20px;
由于Sass编译后会转换生成CSS,可以通过这个网站 在线Sass转CSS 来在线查看转换后的结果。
上面的Sass 代码最终转换 CSS 代码如下:
nav
width: 200px;
background: white;
nav ul
width: 100%;
background: red;
nav ul li
width: 100%;
background: blue;
nav ul li a
color: green;
font-size: 20px;
写起来是不是方便很多,但要注意:嵌套的越深,那么编译生成的 CSS 的语句就越多,同时消耗的资源也会越多。
嵌套选择器列表
由逗号分隔的选择器列表会被 Sass 组合到一个选择器列表中:
.alert, .warning
ul, p
margin-right: 0;
margin-left: 0;
padding-bottom: 0;
转换后的CSS:
.alert ul, .alert p, .warning ul, .warning p
margin-right: 0;
margin-left: 0;
padding-bottom: 0;
嵌套组合符选择器
嵌套使用带有选择符的选择器,我们可以将选择符放在外部选择器的末尾,或者内部选择器的开始位置:
ul >
li
list-style-type: none;
h2
+ p
border-top: 1px solid gray;
p
~
span
opacity: 0.8;
转换后的CSS:
ul > li
list-style-type: none;
h2 + p
border-top: 1px solid gray;
p ~ span
opacity: 0.8;
嵌套中引用父选择器
当你使用嵌套的时候,可能你会需要使用到嵌套外层的父选择器,比如为一个元素 添加伪类 (hover、active、before、after) 的时候,可以用 & 代表嵌套规则外层的父选择器。
a
&:hover
color:red;
&:active
color:blue;
&:before
content:'';
&:after
content:'';
span
&:hover
color:green;
转换后的CSS:
a:hover
color: red;
a:active
color: blue;
a:before
content: "";
a:after
content: "";
a span:hover
color: green;
嵌套中向父选择器添加后缀
向外部选择器添加后缀还是使用 & 符号
.box
width:100px;
&-head
width:100%;
&-title
color:red;
&-body
width:100%;
&-footer
width:100%;
转换后的CSS:
.box
width: 100px;
.box-head
width: 100%;
.box-head-title
color: red;
.box-body
width: 100%;
.box-footer
width: 100%;
嵌套中使用占位符选择器
在 Sass 中占位符以 % 开头,必须通过 @extend
指令调用,如果单独使用的话是不会编译到 CSS 中的,@extend 指令后面会介绍。
%placeholder
width:100px;
height:100px;
color:red;
&:hover
color:blue;
.btn
@extend %placeholder;
font-size: 18px;
.btn2
@extend %placeholder;
font-size: 16px;
转换后的CSS:
.btn2, .btn
width: 100px;
height: 100px;
color: red;
.btn2:hover, .btn:hover
color: blue;
.btn
font-size: 18px;
.btn2
font-size: 16px;
属性嵌套
属性嵌套指是 CSS 属性具有相同的命名空间 (namespace),比如定义字体样式的属性: font-size ; font-weight ; font-family
; 具有相同的前缀 font
,再比如定义边框样式的属性:border-radius ; border-color
; 具有相同的前缀 border
等等。
Sass 允许将属性嵌套在命名空间中,同时命名空间也可以具有自己的属性值
.box
border:
radius: 5px;
color:red;
font:
family:'YaHei';
size:18px;
weight:600;
margin: auto
bottom: 10px;
top: 10px;
;
转换后的CSS:
.box
border-radius: 5px;
border-color: red;
font-family: "YaHei";
font-size: 18px;
font-weight: 600;
margin: auto;
margin-bottom: 10px;
margin-top: 10px;
小结:
Sass 变量
Sass中可以定义变量来表示属性值,以便提高复用,方便修改。
举个例子,假如我们项目中很多地方要设置一个字体颜色为红色,那么我们完全可以把这个颜色抽出来作为一个变量,然后在所有需要设置字体颜色的地方引用这个变量。这样有一个好处就是,假如产品大大说要修改所有字体颜色的时候,我们就不需要每处都去修改了,直接更改变量的值就 OK 了。
变量的声明定义
定义变量以 $
开头: $variable
$variable: red;
.title
color: $variable;
h1
color: $variable;
转换后的CSS:
.title
color: red;
h1
color: red;
Sass 变量的值,支持原来任何 CSS 的属性值都可以作为 Sass 变量的值
$font-family: "YaHei"、"Myriad Pro"; // 字体的属性值
$color: red; // 颜色的属性值
$width: 20px; // 宽度的属性值
$border: 1px solid #000000; // border的属性值
$use-flex-grow: 1; // flex-grow的属性值
变量值的类型可以是:
- 字符串
- 数字
- 颜色值
- 布尔值
- 列表
- Null 值
变量的命名格式
没有什么特殊要求,只要是语义化,方便理解就行,如定义变量名为 $theme-color
,页面中的主要边框颜色,定义为 $main-border-color
等等,也可以根据公司团队的规范要求。
在 Sass 中,使用中划线 “-” 和下划线 “_” 这两种方式是兼容的,也就是说你用中划线声明的变量,也可以使用下划线去引用,比如我定义了变量 $theme-color
,我在引用的时候也可以写成 $theme_color
。
变量的引用
$main-bg-color: blue;
$main-border: 1px solid #cccccc;
$main-font-size: 18px;
$error-text-color: red;
$body-color: $main-bg-color;
body
background-color:$body-color;
.content
font-size:$main-font-size;
background-color:$main-bg-color;
border:$main-border;
.error
font-size:$main-font-size;
color:$error-text-color;
$body-color 这个变量,可以发现,在声明变量时,变量的值也可以引用其他变量
转换后的CSS:
body
background-color: blue;
.content
font-size: 18px;
background-color: blue;
border: 1px solid #cccccc;
.error
font-size: 18px;
color: red;
变量的作用域
与JS一样,变量作用域也分为全局和局部,在局部作用域当中,即便同名,全局变量也不受影响
$main-color: red;
h1
$main-color: green; // 局部变量
color:$main-color;
h2
color:$main-color;
转换后的CSS:
h1
color: green;
h2
color: red;
如果局部的变量想修改或覆盖全局变量,使用 !global 标识符:
$main-color: red;
h1
$main-color: green!global;
color:$main-color;
h2
color:$main-color;
这样编译之后两个都会是green
一般来说我们反复的声明一个重名变量,那么最后一个声明的变量值会覆盖上面所有的,比如像下面这样:
$main-color: red;
$main-color: green;
h1
color:$main-color;
最后编译的时候会使用最后一次声明的变量值,也就是 green , 但是有一种情况:在实际的项目开发中,假如需要你来写一段公共的 Sass 代码给其他开发者使用,那么如果你的代码中声明了 $main-color 这个变量,那么其他开发者在自己页面也声明了 $main-color 这个变量,并且他是在导入你的这段代码之前声明的,那么他的就会被覆盖掉,这是不行的!
可以使用 !default 标识符来解决:
$main-color: red; // 假如这个是其他开发者自己声明的
$main-color: green!default; // 假如这个是你的代码片段声明的
h1
color:$main-color;
转换后的CSS:
h1
color: red;
如果其他开发者没有声明这个变量,就会使用 green 这个用户自己定义的变量值。
实际项目中会抽取一般都会抽离出 1~n 个文件来专门声明 Sass 变量(抽离出几个文件视项目大小而定)
我们一般会在 styles 目录下新建一个 variables.scss 文件来管理声明的全局变量
小结:
Sass 数据类型
Number 类型
在 Sass 中,数字类型支持普通数字,科学计数法,还支持带单位的写法,如 8px 这种,即 Number 类型可能有单位也可能没有单位,而且这是非常常用的。
$main-height: 80px; // 带有单位的 Number 类型
$main-flex-grow: 1; // 不带单位的 Number 类型
$main-num: 5e3; // 使用科学计数法的数字
$main-max-height: 2 * 80px; // 运算
.box
height: $main-height;
flex-grow: $main-flex-grow;
width: $main-num;
max-height: $main-max-height;
转换后的CSS:
.box
height: 80px;
flex-grow: 1;
width: 5000;
max-height: 160px;
Boolean 类型
Boolean 类型无非就两个值,true 和 false ,当然除了直接写的 true 和 false 外,也可以是一些等式、关系运算、或内置函数的结果,不过这些结果最终还是 true 或 false 。一般来说 Boolean 类型都会结合 Sass 判断或者函数来使用,真正直接写在样式中基本是没有的,所以这里你只要知道这个类型就可以。
String 类型
在 Sass 中支持 带引号 和 不带引号 两种方式的字符串,比如 “a” 或者 a ,还支持转义符 **
$string-one: 'Yahei'; // 带引号的字符串
$string-two: Yahei; // 不带引号的字符串
$string-three: '\\"yahei'; // 使用转义符的字符串
.box
font:$string-one;
font-family: $string-two;
font: $string-three;
转换后的CSS:
.box
font: "Yahei";
font-family: Yahei;
font: '"yahei';
Colors类型
$color-one: #ffffff;
$color-two: red;
$color-three: rgb(204, 102, 153);
$color-four: rgba(107, 113, 127, 0.8);
.box
color: $color-one;
background-color: $color-two;
border-color: $color-three;
color: $color-four;
转换后的CSS:
.box
color: #ffffff;
background-color: red;
border-color: #cc6699;
color: rgba(107, 113, 127, 0.8);
Lists 类型
Lists 类型就是数组,列表中包含一系列的值,在 Sass 中列表的元素可以使用逗号或者空格来分隔
$font-list: 'Georgia','Serif'; // 通过逗号分隔元素
$border-list: 1px 2px 3px 4px; // 通过空格分隔元素
$padding-list: 3px,3px 4px 4px; // 混用(不建议)
Maps 类型
$textStyleMap: (
'font-family': 'Georgia',
'font-weight': 600,
'font-size': 18px,
'text-align': center
);
p
font-family: map-get($textStyleMap, 'font-family');
font-weight: map-get($textStyleMap, 'font-weight');
font-size: map-get($textStyleMap, 'font-size');
text-align: map-get($textStyleMap, 'text-align');
转换后的CSS:
p
font-family: "Georgia";
font-weight: 600;
font-size: 18px;
text-align: center;
Null 类型
在 Sass 中它表示缺少值,通常由函数返回。如果说在列表中有 null ,那么在生成 CSS 的时候会忽略该空值。
小结:
Sass 运算
数字运算
p
width: 10px + 20px; // 加法运算 (不能使用不兼容的单位)
height: 500px +50; // 加法运算无单位的数字可以与有单位的一起使用
max-width: 800px - 100px; // 减法
max-height: 400px * 2; // 乘法,一个数值带单位即可
font-size: 30px % 4; // 模运算
转换后的CSS:
p
width: 30px;
height: 550px;
max-width: 700px;
max-height: 800px;
font-size: 2px;
需要注意的地方:
- 不能使用不兼容的单位!(在除法运算中除外),如两个数字相加,不能一个数字单位是 px 另一个数字单位是 em
- 乘法运算,只需要为其中一个数值写上单位即可
- 减法运算,符两边需要都加空格或者都不加空格,也就是说运算符的两边是对称的
上面最后一条,是因为减法运算符 - 不仅仅表示减法,还能表示负数
例如:
p
width: 10px - 5px; // 前后都有空格
width: 10px-5px; // 前后都没有空格
width:10px -5px; // 只有前面有空格
转换后的CSS:
p
width: 5px;
width: 5px;
width: 10px -5px;
圆括号
跟通常意义上的四则运算中的圆括号一样,可以来控制运算顺序,Sass里一般除法中比较有用。
除法运算
在 CSS 中,你要知道 / 这个标识符并不是代表除法的,一些 CSS 的属性值是支持使用 / 来分隔的,所以在 Sass 中直接使用 / 也是会当成分隔符来处理。但是呢,在以下情况下,Sass 将会把 / 视为除法运算:
- 运算符前后的值存储在变量中或由函数返回
- 运算符和前后的值被圆括号所包裹
- 值是另外一个表达式的一部分
$one: 20px / 2;
$two: 10px;
p
width: 200px + 100px / 10; // 值是另外一个运算表达式的一部分
font-size: $one; // 前后的值存储在变量中或由函数返回
border-width: $two / 5; // 前后的值存储在变量中或由函数返回
height: (800px / 2); // 被圆括号所包裹
max-width: 800px / 2; // 会被当作分隔符来处理,而不是除法运算
转换后的CSS:
p
width: 210px;
font-size: 10px;
border-width: 2px;
height: 400px;
max-width: 800px/2;
还有一种情况是:假如我
以上是关于Sass基础入门的主要内容,如果未能解决你的问题,请参考以下文章