sass/scss预处理器的简单理解
❄️篇幅过长,还请耐心阅读实践❄️
CSS预处理(了解)
CSS 本身可能很有趣,但是样式表正变得越来越大、 越来越复杂、越来越难以维护。这就是预处理可以提供帮助的地方。 Sass 为你提供了 CSS 中还不存在的特性,例如变量、 嵌套、混合、继承和其它实用的功能,让编写 CSS 代码变得再次有趣。但此语言无法直接运行,必须先编译(预处理)为CSS再运行
常用css预处理器还有(less、stylus)
less
Less 也是一种动态样式语言,受Sass 影响较大,对CSS赋予了动态语言的特性,如变量,继承,运算,函数,Less 既可以在客户端上运行(借助less.js) ,也可在服务端运行(借助Node.js)。
stylus
2010年产生于node社区,主要用来给Node项目进行CSS预处理支持,人气不如前两者
stylus被称为是一种革命性的新语言,提供一个高效、动态、和使用表达方式来生成css,以供浏览器使用。Stylus同时支持缩进和 CSS常规样式书写规则。需要安装node
stylus 的语法花样多一些,它的文件扩展名是“.styl”,Stylus 也接受标准的css语法,但是他也像Sass老的语法规则,使用缩进控制,同时Stylus也接受不带大括号{}和分号的语法
中文网:https://www.stylus-lang.cn/
SASS/SCSS
sass与scss得关系
Sass 的缩排语法,对于写惯css前端的web开发者来说很不直观,也不能将css代码加入到Sass 里面,因此 sass 语法进行了改良,Sass 3就变成了Scss(Sassy CSS)。与原来的语法兼容,只是用 { } 取代了原来的缩进。(就是说以前版本使用缩进风格 sass,最新版本改为{ } scss)
入门
准备
创建相应文件及文件夹
将对应文件填充内容
index.scss
html{
color: #333;
}
p{
color: #333;
}
基于node的npm安装全局的sass运行工具
打开vscde终端,安装sass
检测是否安装成功
执行sass命令使其index.scss生成对应index.css
在终端执行该命令 sass index.scss css/index.css
会将当前目录的index.scss 文件编译到css文件夹下,编译为对应css文件
》》可见也会生成对应.map文件,这个文件是用来干嘛的?
.map文件是一个json格式的文件,可以直接在浏览器中调试sass源文件。
简化操作
每次修改index.scss文件都要执行命令进行编译有点麻烦
sass提供watch参数用于侦听某个scss文件以及文件夹
在终端执行该命令sass --watch index.scss:css/index.css
变量
sass让人们受益的一个重要特性就是它为css引入了变量。你可以把反复使用的css属性值定义成变量,然后通过变量名来引用它们,而无需重复书写这一属性值。或者,对于仅使用过一 次的属性值,你可以赋予其一个易懂的变量名,让人一眼就知道这个属性值的用途。
格式:$变量名: css属性值;
index.scss
// 定义变量
$nav-color: #F90;
$highlight-color: #F90;
nav {
$width: 100px; // 定义变量
width: $width; // 引用变量
color: $nav-color;
}
.selected {
border: 1px solid $highlight-color;
}
// 变量中也可以使用上面个定义的变量
$highlight-border: 1px solid $highlight-color;
.input {
border: $highlight-border;
}
/* 编译结果
nav {
width: 100px;
color: #F90;
}
.selected {
border: 1px solid #F90;
}
.input {
border: 1px solid #F90;
}
*/
命名规则
sass的变量名可以与css中的属性名和选择器名称相同,包括中划线(-)和下划线(_)。
这完全取决于个人的喜好,有些人喜欢使用中划线来分隔变量中的多个词(如$ highlight-color),而有些人喜欢使用下划线(如$highlight_color)。使用中划线的方式更为普遍。
嵌套
css中重复写选择器是非常恼人的。如果要写一大串指向页面中同一块的样式时,往往需要一遍又一遍地写同一个选择器
index.scss
/*
// 原始写法
// #content article h1 {
// color: #333
// }
// #content article p {
// margin-bottom: 1.4em
// }
// #content aside {
// background-color: #EEE
// }
*/
/* scss写法*/
#content {
article {
h1 {
color: #333
}
p {
margin-bottom: 1.4em
}
}
aside {
background-color: #EEE
}
}
/*编译结果
#content article h1 {
color: #333;
}
#content article p {
margin-bottom: 1.4em;
}
#content aside {
background-color: #EEE;
}
*/
父选择器的标识符&
& 表示当前嵌套层的选择器
article a {
color: blue;
&:hover { /*此时的 & 表示 article a*/
color: red
}
}
嵌套属性
在sass中,除了CSS选择器,属性也可以进行嵌套。尽管编写属性涉及的重复不像编写选择器那么糟糕,但是要反复写border-style、border-width、border-color以及border-*等也是非常烦人的。在sass中,你只需敲写一遍border
nav {
border: {
style: solid;
width: 1px;
color: #ccc;
}
}
混合
混合指令(Mixin)用于定义可重复使用的样式
定义混合指令
- 方式1
混合指令的用法是在 @mixin 后添加名称与样式,比如名为 large-text 的混合通过下面的代码定义:@mixin large-text { font: { family: Arial; size: 20px; weight: bold; } &>div{ //也可以用 & 引用父选择器 border: 1px solid #333; } color: #ff0000; }
- 方式2
$ color、$ width参数用于给混合指令中的样式设定变量,并且赋值使用@mixin sexy-border($color, $width) { border: { color: $color; width: $width; style: dashed; }
引用混合样式
- 方式1使用
.page-title { @include large-text; padding: 4px; margin-top: 10px; }
- 方式2使用
p { @include sexy-border(blue, 100px); }
继承/扩展
@extend
用于扩展当前选择器中得样式
index.scss
.public-style-one {
font-size: 16px;
}
.public-style-two {
font-size: 18px;
}
.font-info {
@extend .public-style-one;
@extend .public-style-two;
background-color: #fff;
}
/*编译结果
.public-style-one, .font-info {
font-size: 16px;
}
.public-style-two, .font-info {
font-size: 18px;
}
.font-info {
background-color: #fff;
}
*/
导入
@import
》》注意
原生css 的 @import 规则是可以在一个 css 文件导入其他 css 文件,但是需要执行到它时才能触发浏览器去下载它所 import 来的 css 文件,导致页面加载起来特别慢,还不如直接在里面写一大坨标签的引入效率高。
Sass 拓展了原生css的 @import
功能,允许其导入 SCSS 或 Sass 文件。被导入的文件将合并编译到同一个 CSS 文件中,另外,被导入的文件中所包含的变量或者混合指令 (mixin) 都可以在导入的文件中使用。
通常,@import 寻找 Sass 文件并将其导入,但在以下情况下,@import 仅作为普通的 CSS 语句,不会导入任何 Sass 文件。(如果以下规则有符合,sass的@import就会按原生的css@import导入方式)
- 文件拓展名是 .css;
- 文件名以 http:// 开头;
- 文件名是 url();
- @import 包含 media queries(媒体查询)。
如果不在上述情况内,文件的拓展名是 .scss 或 .sass,则导入成功。没有指定拓展名,Sass 将会试着寻找文件名相同,拓展名为 .scss 或 .sass 的文件并将其导入。
-
创建导入文件
-
填入相关代码
$baseWidth: 100px; body { margin: 0; padding: 0; }
-
在index.scss中引入此scss文件,可省略后缀
@import 'base-style'; .font-info { width: $baseWidth; }
》》注意
如果需要导入 SCSS 或者 Sass 文件,但又不希望将其编译为 CSS,只需要在文件名前添加下划线,这样会告诉 Sass 不要编译这些文件,但导入语句中却不需要添加下划线。
》》例如
将文件命名为 _base-style.scss,便不会编译 _base-style.css 文件。
注意,不可以同时存在添加下划线与未添加下划线的同名文件,添加下划线的文件将会被忽略。
@use
从其他Sass样式表加载mixin,function和变量,并将来自多个样式表的CSS组合在一起,@use
加载的样式表被称为“模块”,多次引入只包含一次。
@use也可以看作是对@import的增强
格式:@use ‘’ [as alias|namespace]
例如:
@use “base-style” as baseStyle;
@use “base-style” 引入base-style的.scss文件或.css文件
as baseStyle 将引入的模块命名为baseStyle,使用其数据时,比如变量需要baseStyle. 的方式访问
@use “base-style”; 默认以文件名作为模块名,可通过as alias取别名
注意:@use必须声明在其他代码之上
base-style.scss
$font-size: 20px;
$column-width: 100px;
* {
margin: 0;
padding: 0;
font-size: $font-size;
color: #333;
}
@function column-width($width) {
@return $column-width + $width;
}
@mixin bgColor($bg-color: #f2f2f2) {
background-color: $bg-color;
}
index.scss
@use "base-style" as baseStyle;
/*访问baseStyle模块中的数据*/
div {
font-size: baseStyle.$font-size;
width: baseStyle.column-width(100px);
@include baseStyle.bgColor();
}
/* 编译结果
* {
margin: 0;
padding: 0;
font-size: 20px;
color: #333;
}
div {
font-size: 20px;
width: 200px;
background-color: #f2f2f2;
}
*/
定义私有成员
如果引入的模块内部有变量只想在模块内使用,可使用 - 或 _ 定义在变量头即可
base-style.scss
$-font-size:14px;
* {
margin: 0;
padding: 0;
font-size: $-font-size;
color: #333;
}
index.scss
@use "base-style" as baseStyle;
div {
font-size: baseStyle.$-font-size; /*报错 Error: Private members can't be accessed from outside their modules.*/
}
定义默认值
通过 !default
能给变量定义默认值
base-style.scss
$font-size:14px !default;
* {
margin: 0;
padding: 0;
font-size: $font-size;
color: #333;
}
index.scss
@use引入时可通过with(…)
修改默认值
@use "base-style" as baseStyle with($font-size: 20px);
div {
font-size: baseStyle.$font-size;
}
@use使用总结
- @use引入同一个文件多次,不会重复引入,而@import会重复引入
- @use引入的文件都是一个模块,默认以文件名作为模块名,可通过as alias取别名
- @use引入多个文件时,每个文件都是单独的模块,相同变量名不会覆盖,通过模块名访问,而@import变量会被覆盖
- @use方式可通过 @use ‘xxx’ as *来取消命名空间,建议不要这么做
- @use模块内可通过 − 或 - 或 −或来定义私有成员,也就是说或者-开头的Variables mixins functions 不会被引入
- @use模块内变量可通过!default 定义默认值,引入时可通用with(…)的方式修改
- 可定义-index.scss或_index.scss来合并多个scss文件,它@use默认加载文件
@forward
通过@forward
加载一个模块的成员,并将这些成员当作自己的成员对外暴露出去,类似于类似于 es6 的 export …,通常用于跨多个文件组织 Sass 库
(相当于中转站,通过@forward引入scss文件并将引入scss文件中的变量、混合、函数等抛出,当其他scss文件用@use引入此模块时可使用)
新建文件transfer.scss
base-style.scss
$font-size: 14px;
$column-width: 100px;
* {
margin: 0;
padding: 0;
font-size: $font-size;
color: #333;
}
@function column-width($width) {
@return $column-width + $width;
}
@mixin bgColor($bg-color: #f2f2f2) {
background-color: $bg-color;
}
transfer.scss
@forward "base-style";
index.scss
@use "transfer" as transfer;
div {
font-size: transfer.$font-size;
width: transfer.column-width(100px);
@include transfer.bgColor();
}
选择性转发
既然可以中转,那也可以控制中转的内容;默认情况下,@forward 会将一个模块中所有成员都转发,如果只想转发某些成员,当你不想转发所有变量、函数、混入时,可使用。
格式:
@forward "module" hide $var, mixinName, fnName
禁止转发某些成员
@forward "module" show $var, mixinName, fnName
只转发某些成员
例如:
@forward "base-style" hide $font-size, bgColor;
转发时定义前缀
格式:@forward "module" as m-*
transfer.scss
@forward "base-style" as b-*;
index.scss
@use "transfer" as transfer;
div {
font-size: transfer.$b-font-size;
width: transfer.b-column-width(100px);
@include transfer.b-bgColor();
}
转发时配置模块成员的默认值
base-style.scss
$font-size:14px !default;
* {
margin: 0;
padding: 0;
font-size: $font-size;
color: #333;
}
transfer.scss
@forward "base-style" as b-* with($font-size: 30px);
@use与@forward一起使用的情况
当一个模块里面须要同时使用@use与@forward时,先使用@forwar后再使用@use
函数
Sass支持自定义函数,并且SassScript 也定义了多种函数,有些甚至可以通过普通的 CSS 语句调用,比如
p {
color: hsl(0, 100%, 50%);
}
自定义函数
格式:@function name($var){ 函数体 @return 返回值}(与js自定义函数相似)
$grid-width: 40px;
$gutter-width: 10px;
@function grid-width($n) {
@return $n * $grid-width +($n - 1) * $gutter-width;
}
#sidebar {
width: grid-width(5);
}
SassScript
在 CSS 属性的基础上 Sass 提供了一些名为 SassScript 的新功能。 SassScript 可作用于任何属性,允许属性使用变量、算数运算等额外功能。(就是有JavaScript相似的功能去操作样式)
数据类型 (Data Types)
SassScript 支持6种主要的数据类型:
- 数字:1, 2, 13, 10px
- 字符串:有引号字符串与无引号字符串,“foo”, ‘bar’, baz
- 颜色:blue, #04a3f9, rgba(255,0,0,0.5)
- 布尔型,true, false
- 空值:null
- 数组 (list):用空格或逗号作分隔符,1.5em 1em 0 2em, Helvetica, Arial, sans-serif
- maps,:相当于 JavaScript 的 object,(key1: value1, key2: value2)
有数据类型那当然也避免不了数据的运算👇
- 数字运算
SassScript 支持数字的加减乘除、取整等运算 (+, -, *, /, %),如果必要会在不同单位间转换值。 - 关系运算
<, >, <=, >= 也可用于数字运算,相等运算 ==, != 可用于所有数据类型。
index.scss
$pWidth: 100px;
$pHeight: 100px;
p {
width: $pWidth * 2;
height: $pHeight * 2;
}
/* 编译结果
p {
width: 200px;
height: 200px;
}
*/
插值语句 #{ }
通过 #{ }
插值语句可以在选择器或属性名中使用变量
index.scss
$name: foo;
$attr: border;
p.#{$name} {
#{$attr}-color: blue;
}
/*编译结果
p.foo {
border-color: blue;
}
*/
控制指令
-
@if
格式:@if 条件{ 样式… } @else if 条件{ 样式 }
$theme: dark; body { @if $theme == dark { background-color: black; } @else if $theme == light { background-color: white; } @else { background-color: grey; } } /*编译结果 body{ background-color: black; } */
-
@for
格式:@for $var from <start> through <end> {循环体}
,或者@for $var from <start> to <end>{循环体}
(与js普通for循环相似)
through :当使用 through 时,条件范围包含 与 的值
to :使用 to 时条件范围只包含 的值不包含 的值
$var 可以是任何变量名,比如 $i
< start> 和 < end> 必须是整数值 start为开始值 比如 1,end为结束值 比如10@for $i from 1 through 3 {//循环从1开始到3结束 包含3 .item-#{$i} { width: 100px * $i; } } /*编译结果 .item-1 { width: 100px; } .item-2 { width: 200px; } .item-3 { width: 300px; } */
@for $i from 1 to 3 {//循环从1开始到3结束 不包含3 .item-#{$i} { width: 100px * $i; } } /* 编译结果 .item-1 { width: 100px; } .item-2 { width: 200px; } */
-
@each
格式:@each $var in <list>{循环体}
(与js中的forEach相似)
$var 可以是任何变量名,比如 $length 或者 $name,
< list> 是一连串的值,也就是值列表。是sass数据类型的数组list类型$icons: success error warning; @each $item in $icons { //循环$icons变量数组 .icon-#{$item} { background-image: url('../images/icons/#{$item}.png'); } } /*编译结果 .icon-success { background-image: url("../images/icons/success.png"); } .icon-error { background-image: url("../images/icons/error.png"); } .icon-warning { background-image: url("../images/icons/warning.png"); } */
-
@while
格式:@while 条件{ 循环体+结束条件}
(与js的while相似)
@while 指令重复输出格式直到表达式返回结果为 false。这样可以实现比 @for 更复杂的循环,只是很少会用到。$i: 6; @while $i > 0 { .item-#{$i} { width: 2em * $i; } $i: $i - 2; } /* 编译结果 .item-6 { width: 12em; } .item-4 { width: 8em; } .item-2 { width: 4em; } */
输出格式
sass编译之后输出的css风格
可使用该命令进行体验
sass --watch index.scss:css/index.css --style compressed
nested(默认)
嵌套缩进的css代码
#main {
color: #fff;
background-color: #000; }
#main p {
width: 10em; }
.huge {
font-size: 10em;
font-weight: bold;
text-decoration: underline; }
expanded
没有缩进,像正常手写的css代码
#main {
color: #fff;
background-color: #000;
}
#main p {
width: 10em;
}
.huge {
font-size: 10em;
font-weight: bold;
text-decoration: underline;
}
compact
简洁格式的css代码
#main { color: #fff; background-color: #000; }
#main p { width: 10em; }
.huge { font-size: 10em; font-weight: bold; text-decoration: underline; }
compressed
压缩后的css代码
#main{color:#fff;background-color:#000}#main p{width:10em}.huge{font-size:10em;font-weight:bold;text-decoration:underline}
到这里就结束了,后续还会更新 css 系列相关,还请持续关注!
感谢阅读,若有错误可以在下方评论区留言哦!!!
推荐文章👇
SASS用法指南 —— 阮一峰