本文是以自己的理解起的结构,要看详细的帮助文档,参阅这里:https://sass-lang.com/documentation/
本文在线例子:https://kylebing.cn/test/scss/
目前CSDN还没有实现对SCSS语法的高亮支持,凑合看吧,或者粘贴到自己的编辑器中查看
less和sass是两种css预编译语言,就是说通过less或者scss写的代码最终都会被编译成css再使用。其目的是为了更快、更结构的编写css文件,都能使用 变量、运算符、判断、方法等等。
scss与sass的区别(这里先不讲less):
初学者最好用scss而非sass,sass在你追求代码简洁的时候用,来看个对比
最好用 JetBrains 系列软件(webStormphpStormIDEA等)开发,里面添加对于scss的File Watcher即可,在每次scss文件改变的时候,程序都会自动编译scss到css。
或者在vue单文件项目中直接在<style lang='scss'></style>中使用scss
scss本身就支持拆分成多文件,再通过mixin整合起来。
关于如何添加scss支持,看这里: https://blog.csdn.net/KimBing/article/details/100532939
写一个.btn类并支持:hover:active样式
css
.btn { /* btn 初始样式 */ } .btn:hover{ /* :hover 样式 */ } .btn:active{ /* :active 样式 */ }
scss
.btn{ // btn 初始样式 &:hover{ // hover 样式 } &:active{ // active 样式 } }
在scss,sass,less中&都代指父类
上面这个例子中的&代指.btn
可以看出scss的结构要比css清晰,并且写的也要更少。
下面的scss在使用中就会生成上面的css。
而这还只是皮毛,保证你用过scss之后就不会再用css写样式了。
变量是以$开头的,可以是颜色,长度,数值,等等。
像 js 的变量一样,scss的变量也是有作用域的,也就是说内部声明的变量是无法在外面使用的,如果想让内部的变量在外部可访问,需要在变量值后面添加!global声明。
(还可以通过添加!default给变量设置默认值,这个在写一个样式库的时候比较实用,避免别人在没有给变量赋值之前使用)
$变量名: 变量值
// Colors $red: #CD594B !global; $yellow: #F8CE5E; $green: #4B9E65; $yellow: #5A8DEE; // Unites $btn-padding: 4px; $btn-lineheight: 26px;
实际使用中:
scss
.btn-success { background-color: $green; line-height: $btn-lineheight; color: #fff; }
生成 css
.btn-success { background-color: #4B9E65; line-height: 26px; color: #fff; }
将变量直接嵌入字符串,需要用#{ 变量 }(类似 ES6 中模板字符串中的${ 变量 })
其实#{}中是可以插入任意东西的,这里只用到了插入变量,还可以插入方法等等,高级用法。
scss
$bg-path: "./img" .card{ background: url("#{$bg-path}/card-bg.png" center center); }
css
.card{ background: url("./img/card-bg.png" center center); }
通过@import可以把多个文件结合到一起
有了这个功能,就可以通过功能拆分scss文件,使其更结构化,比如,可以分成:变量类,按钮类,列表类,字体类,排版类等等。
拆分成多个文件的时候,以_开头命名的文件,不会被像phpStorm中的file watcher自动预编译成css文件,less没有这效果,在这一点上scss很不错。
比如,我一个项目的css结构是这样的:以_开头的都是整个项目的css的结构部分,像底部按键、表单、按钮、通用方法等。最后都整合在pay.scss中
css/ ├── _agent.scss ├── _form.scss ├── _mixin.scss ├── _navbar.scss ├── _normalize.scss ├── _regist.scss ├── _reset.scss ├── _tabbar.scss ├── _trade.scss ├── _trand-time.scss ├── _trand-tradition.scss ├── _usercenter.scss ├── _utility.scss ├── _variables.scss ├── _wallet.scss ├── pay.css ├── pay.css.map └── pay.scss
_variables.scss
$bg-btn: #ddd; $color-btn: #444;
btn.scss
@import "_variables"; .btn{ display: inline-block; padding: 3px 6px; background-color: $bg-btn; color: $color-btn; }
生成 css
.btn{ display: inline-block; padding: 3px 6px; background-color: #ddd; color: #444; }
这个是最常用的,通过@mixin定义一个类或方法,在其它地方通过@include引用这个方法或类。
如果是方法,还可以定义默认值,也就是说可以某些时候,可以传部分参数。
直接看例子
scss
// @mixin 如果没有调用,不会被渲染 @mixin rounded($conor: 5px){ // 定义 mixin 并设置默认值 5px -webkit-border-radius: $conor; -moz-border-radius: $conor; border-radius: $conor; } .btn-rounded{ @include rounded(); // 这里引用上面的 mixin,默认值 5px } .btn-big-rounded{ @include rounded(10px); // 这里引用上面的 mixin,并设置值 10px }
生成 css
.btn-rounded{ -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; } .btn-big-rounded{ -webkit-border-radius: 10px; -moz-border-radius: 10px; border-radius: 10px; }
扩展
mixin 想输入多个参数的时候 参数可以这样写
@mixin border-radius($conor...){ -webkit-border-radius: $conor; -moz-border-radius: $conor; border-radius: $conor; }
有些时候,需要写的某个类里,包含另一个类的所有声明。
如: 警告按钮,包含所有警告颜色类的内容。
scss
.danger{ background-color: #FF3B30; } .round{ -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; } .btn{ display: inline-block; padding: 3px 6px; } .btn-danger{ @extend .danger, .round, .btn; }
css
.danger, .btn-danger { background-color: #FF3B30; } .round, .btn-danger { -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; } .btn, .btn-danger { display: inline-block; padding: 3px 6px; }
@extend注意事项:
不能继承@extend .danger.text这种连续组合的类,应该写为@extend .danger, .text
呃,没什么说的,就是ifelse《官方文档:if else》
SCSS
@if $name == normal { // 判断 $name 是否为 'normal' color: #333; // 如果是,内部文字颜色为 #333 border: 1px solid darken($color, 20%); } @else { color: white; border: 1px solid darken($color, 5%); }
跟js中的Array.each(item=>{})一样,遍历变量所存在的所有数据。
比如下面的例子,会遍历$btn-styles中的三个字符串
$btn-styles: "normal", "primary", "danger"; @each $type in $btn-styles { .btn-#{$type}{ background-color: white; } }
CSS
.btn-normal { background-color: white; } .btn-primary { background-color: white; } .btn-danger { background-color: white; }
for用于基于数字的遍历,有两种使用方法
举个最常用的例子,生成pb-1pb-2…pb-8
SCSS
@for $gap from 1 through 8 { .pb-#{$gap} { padding-bottom: 10px * $gap; } }
CSS
.pb-1 { padding-bottom: 10px; } .pb-2 { padding-bottom: 20px; } .pb-3 { padding-bottom: 30px; } .pb-4 { padding-bottom: 40px; } .pb-5 { padding-bottom: 50px; } .pb-6 { padding-bottom: 60px; } .pb-7 { padding-bottom: 70px; } .pb-8 { padding-bottom: 80px; }
详见:https://sass-lang.com/documentation/functions
不知道别人,反正我最常用的就是颜色方法了。列举常用的颜色方法
lighten (颜色, 百分比) // 调亮 darken (颜色, 百分比) // 调暗 saturate (颜色, 百分比) // 调高饱和度 desaturate (颜色, 百分比) // 降低饱和度 transparentize (颜色, 0.0-1.0) // 透明度,注意这里接收的不是百分比,是 0.0-1.0 的小数值
本文在线例子:https://kylebing.cn/test/scss/
SCSS
$green: #4B9E65; .green-original { background-color: $green; } .green-lighten { background-color: lighten($green,20%); } .green-darken { background-color: darken($green,20%); } .green-saturate { background-color: saturate($green,20%); } .green-desaturate { background-color: desaturate($green,20%); } .green-transparent { background-color: transparentize($green, 0.2); }
CSS
.green-original { background-color: #4B9E65; } .green-lighten { background-color: #88c79c; } .green-darken { background-color: #2a5939; } .green-saturate { background-color: #34b55c; } .green-desaturate { background-color: #62876e; } .green-transparent { background-color: rgba(75, 158, 101, 0.8); }
方法以@function开头,以@return结尾,也就是说,方法的定义,必须要有返回值
详见:https://sass-lang.com/documentation/at-rules/function
方法的使用跟上面讲到的颜色方法是一样的。
方向在定义完成后,可以直接写方法名调用,不需要添加前面的@符号,如:
知道文档的 HTML 根字体大小是14px,目前需要进行动态尺寸适配,知道其它地方的字体在像素单位上的大小,比如.font-size-normal的字体大小是16px,如何快速方便的计算出(16/14)rem这样的尺寸呢?对,此时就用到了 Function,非常方便。
rem单位是以文档根元素(也就是<html></html>)字体大小为基准的单位,设置成rem为单位的尺寸后,修改<html>的字体大小,文档内的以rem为单位的尺寸都会跟着变化。
这是在适配方面很重要的知识点
SCSS
// 比较 $root: 14; // 定义一个方法用于换算尺寸的方法 // #{} 是输出字符串的,上面有讲 @function size($size) { @return #{$size/$root}rem } .font-size-normal { font-size: size(16); }
得出来的CSS是这样的
.font-size-normal { font-size: 1.1428571429rem; }
像js的console.logconsole.error一样,用于输出提示信息
通用
CSS
顶级
表达式
运算符
其它
/* 多行注释 可以多行 在非压缩模式下,这种注释会被输出到 css 中 */ // 单行注释 // 这种注释不会输出到 css 中
CSS 本身自带一些方法,大多数方法都能与SCSS方法和平共存,但有些会产生冲突,如url()
如果url()传入的参数是有效的带引号的 url,sass不会处理它,但还可以往其中插入变量,如果不是有效的带引号的 url,带有方法或变量的,sass就把它当成正常的方式识别。如:
$bg-path: "./pics" .card-bg{ background: url("#{$bg-path}/card-bg.png") center center; } // 或 .card-bg{ background: url($bg-path+"/card-bg.png") center center; }
都会输出为
.card-bg{ background: url("./pics/card-bg.png") center center; }
学会上面的所有内容,我们来写一个例子。
比如,你需要写一个按钮库.btn-success,.btn-danger,.btn-normal,.btn-warning,如果单个定义的话,会很麻烦,现在有了 SCSS,就可以很方便的实现了。
完成后,效果是这样的:
本文在线例子:https://kylebing.cn/test/scss/
SCSS
// 定义基础颜色 // 一般在项目中会写在 _variables.scss 文件中 $green : #4CD964; $syan : #5AC8FA; $blue : #007AFF; $purple : #5856D6; $magenta : #FF2D70; $red : #FF3B30; $orange : #FF9500; $yellow : #FFCC00; $gray : #8E8E93; // 定义需要实现的按钮名和颜色,键值对 $btn-types: ( "normal": white, "primary": $blue, "success": $green, "danger": $red, "warning": $orange, "second": $gray, ); /**************************** 把一些常用的需要多平台适配的(-webkit-)做成 mixin 方便调用,写的时候代码也简洁 像这种还有 box-shadow transform transition animation 等等 一般在项目中都单独定义成一个文件 _utility.scss,直接引用使用,也方便。 这里只是提一下,可能会对你有所启发 */ @mixin border-radius($value){ -webkit-border-radius: $value; -moz-border-radius: $value; border-radius: $value; } /**************************** 这里定义最常用的通用方法,比如 .link .btn .block .hidden 一般保存为 _normalize.scss 文件 */ .unselectable{ -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } // .btn 里只放 button 最基础的行为和动作 // 下面循环中的 .btn-xxxx 只处理按钮的颜色变化,这样明了 .btn { padding: 6px 10px; text-align: center; font-size: 1rem; cursor: pointer; margin-right: 5px; @extend .unselectable; // 引用其它类的内容作为自己的内容,也就是扩展 @include border-radius(5px); // 调用 mixin &:active{ transform: translateY(2px); } } @each $name, $color in $btn-types { .btn-#{$name} { @if $name == normal { // 判断 button 名 是否为 'normal' color: #333; // 如果是,内部文字颜色为 #333 border: 1px solid darken($color, 20%); } @else { color: white; border: 1px solid darken($color, 5%); } background-color: $color; &:hover{ background-color: lighten($color, 5%); } &:active{ border-color: transparent; background-color: darken($color, 15%); // 点击的时候按钮背景颜色深 15% } } }
上面的scss输出为下面的内容,有没有很强大
/* buttons */ .unselectable, .btn { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } .btn { padding: 6px 10px; text-align: center; font-size: 1rem; cursor: pointer; margin-right: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; } .btn:active { transform: translateY(2px); } .btn-normal { color: #333; border: 1px solid #cccccc; background-color: white; } .btn-normal:hover { background-color: white; } .btn-normal:active { border-color: transparent; background-color: #d9d9d9; } .btn-primary { color: white; border: 1px solid #006ee6; background-color: #007AFF; } .btn-primary:hover { background-color: #1a87ff; } .btn-primary:active { border-color: transparent; background-color: #0055b3; } .btn-success { color: white; border: 1px solid #37d552; background-color: #4CD964; } .btn-success:hover { background-color: #61dd76; } .btn-success:active { border-color: transparent; background-color: #26b33e; } .btn-danger { color: white; border: 1px solid #ff2317; background-color: #FF3B30; } .btn-danger:hover { background-color: #ff534a; } .btn-danger:active { border-color: transparent; background-color: #e30c00; } .btn-warning { color: white; border: 1px solid #e68600; background-color: #FF9500; } .btn-warning:hover { background-color: #ffa01a; } .btn-warning:active { border-color: transparent; background-color: #b36800; } .btn-second { color: white; border: 1px solid #818187; background-color: #8E8E93; } .btn-second:hover { background-color: #9b9b9f; } .btn-second:active { border-color: transparent; background-color: #68686d; }
其实这里可以使用渐变优化按钮颜色的,你可以考虑如何实现哟,加油。
给个提示: 基础颜色不需要变,只需要用颜色方法对基础颜色进行微调即可产出渐变需要的颜色