❄️篇幅过长,还请耐心阅读实践❄️
CSS 本身可能很有趣,但是样式表正变得越来越大、 越来越复杂、越来越难以维护。这就是预处理可以提供帮助的地方。 Sass 为你提供了 CSS 中还不存在的特性,例如变量、 嵌套、混合、继承和其它实用的功能,让编写 CSS 代码变得再次有趣。但此语言无法直接运行,必须先编译(预处理)为CSS再运行
Less 也是一种动态样式语言,受Sass 影响较大,对CSS赋予了动态语言的特性,如变量,继承,运算,函数,Less 既可以在客户端上运行(借助less.js) ,也可在服务端运行(借助Node.js)。
中文网:https://less.bootcss.com/
2010年产生于node社区,主要用来给Node项目进行CSS预处理支持,人气不如前两者
stylus被称为是一种革命性的新语言,提供一个高效、动态、和使用表达方式来生成css,以供浏览器使用。Stylus同时支持缩进和 CSS常规样式书写规则。需要安装node
stylus 的语法花样多一些,它的文件扩展名是“.styl”,Stylus 也接受标准的css语法,但是他也像Sass老的语法规则,使用缩进控制,同时Stylus也接受不带大括号{}和分号的语法
中文网:https://www.stylus-lang.cn/
Sass 的缩排语法,对于写惯css前端的web开发者来说很不直观,也不能将css代码加入到Sass 里面,因此 sass 语法进行了改良,Sass 3就变成了Scss(Sassy CSS)。与原来的语法兼容,只是用 { } 取代了原来的缩进。(就是说以前版本使用缩进风格 sass,最新版本改为{ } scss)
index.scss
html{
color: #333;
}
p{
color: #333;
}
在终端执行该命令 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)用于定义可重复使用的样式
@mixin large-text {
font: {
family: Arial;
size: 20px;
weight: bold;
}
&>div{ //也可以用 & 引用父选择器
border: 1px solid #333;
}
color: #ff0000;
}
@mixin sexy-border($color, $width) {
border: {
color: $color;
width: $width;
style: dashed;
}
.page-title {
@include large-text;
padding: 4px;
margin-top: 10px;
}
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;
}
*/
》》注意
原生css 的 @import 规则是可以在一个 css 文件导入其他 css 文件,但是需要执行到它时才能触发浏览器去下载它所 import 来的 css 文件,导致页面加载起来特别慢,还不如直接在里面写一大坨标签的引入效率高。
Sass 拓展了原生css的 @import
功能,允许其导入 SCSS 或 Sass 文件。被导入的文件将合并编译到同一个 CSS 文件中,另外,被导入的文件中所包含的变量或者混合指令 (mixin) 都可以在导入的文件中使用。
通常,@import 寻找 Sass 文件并将其导入,但在以下情况下,@import 仅作为普通的 CSS 语句,不会导入任何 Sass 文件。(如果以下规则有符合,sass的@import就会按原生的css@import导入方式)
如果不在上述情况内,文件的拓展名是 .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 文件。
注意,不可以同时存在添加下划线与未添加下划线的同名文件,添加下划线的文件将会被忽略。
从其他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;
}
通过@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时,先使用@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);
}
在 CSS 属性的基础上 Sass 提供了一些名为 SassScript 的新功能。 SassScript 可作用于任何属性,允许属性使用变量、算数运算等额外功能。(就是有JavaScript相似的功能去操作样式)
SassScript 支持6种主要的数据类型:
有数据类型那当然也避免不了数据的运算
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
,或者 @for $var from
(与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
(与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
嵌套缩进的css代码
#main {
color: #fff;
background-color: #000; }
#main p {
width: 10em; }
.huge {
font-size: 10em;
font-weight: bold;
text-decoration: underline; }
没有缩进,像正常手写的css代码
#main {
color: #fff;
background-color: #000;
}
#main p {
width: 10em;
}
.huge {
font-size: 10em;
font-weight: bold;
text-decoration: underline;
}
简洁格式的css代码
#main { color: #fff; background-color: #000; }
#main p { width: 10em; }
.huge { font-size: 10em; font-weight: bold; text-decoration: underline; }
压缩后的css代码
#main{color:#fff;background-color:#000}#main p{width:10em}.huge{font-size:10em;font-weight:bold;text-decoration:underline}
到这里就结束了,后续还会更新 css 系列相关,还请持续关注!
感谢阅读,若有错误可以在下方评论区留言哦!!!