前言
今时不同来日,能叫咱们切图仔的只能是咱们本人!
在 JavasScrip
框架满天飞的年代,前端三板斧之一的 CSS
也前前后后涌出 Sass
、Less
、Stylus
等多款 CSS
预处理框架。
明天咱们要讲的就是其中的的老大哥 Sass
的升级版 Scss
,Scss
给咱们提供了变量、循环、继承、混入、函数等一系列弱小的性能以不便咱们开发。
以前感觉 Scss
简略,起初发现,简略是真的简略,我菜也是真的菜😞😞😞
如果文章对你有帮忙的话,记得一键三连哟。有问题和纳闷的话也能够在评论区留言。我会第一工夫回复大家,如果感觉我的文章哪里有知识点谬误的话,也恳请可能告知,把错的货色了解成对的,无论在什么行业,都是致命的。
日常博客记录在语雀,欢送关注 语雀文档。
Scss 和 Sass
Sass
从第三代开始,放弃了缩进式格调,并且齐全向下兼容一般的 CSS
代码,这一代的 Sass
也被称为Scss
。
文档
单文件编译能够在上面的网站进行操作,多文件编译见下下节,中文文档缺失的货色挺多的,有条件的能够翻看英文文档。
- 中文文档:https://www.sass.hk
- 英文文档:https://sass-lang.com/documen…
CSS
转Scss
:https://www.sass.hk/css2sassScss
转CSS
:https://www.sassmeister.com
Sass 版本
Sass
有三个版本 Dart Sass
、libsass
和Ruby Sass
:
Dart Sass
,用Dart
语言写的sass
实现,于 2016 年 11 月 1 日公布alpha
版本,版本1.23.0
之后齐全反对模块化机制。libSass
也就是俗称的node-sass
,用c/c++
实现的sass
版本,应用十分宽泛。node-sass
是绑定了libsass
的nodejs
库,能够极快的将.scss
文件编译为.css
文件,这个装置过程……,懂的都懂,官网也不举荐再应用了。Ruby Sass
,是最后的Sass
实现,然而 2019 年 3 月 26 日被进行了,当前也不会再反对,使用者须要迁徙到别的实现上。
环境配置
中文文档的装置教程是 Ruby Sass
,集体举荐应用npm
装置Dart Sass
,这也是官网举荐的形式。
全局装置
npm
默认装置的是 Dart Sass
了。
npm install -g sass
我的项目构造
code
--css
--index.scss
--dist
监听运行
应用命令行操作,监听文件夹下的 scss
文件并输入为 css
文件,如果是 webpack
我的项目,则须要应用sass-loader
。
sass --style=expanded -w css:dist --no-source-map
Live Sass Compiler
如果你应用的 VSCode
的Live Sass Compiler
插件,能够参考我的配置,这个插件用的 Sass
版本是LibSass3.5.4
,对有些指令存在兼容性和不反对的状况。
"liveSassCompile.settings":{
"generateMap":false,
"formats":[
{
"format": "expanded",
"savePath": "~/css/",
}
]
}
输入格局
嘿嘿,上面注释术语都同对立改为小写哈。scss
提供了四种输入格局,在命令行中应用 --style
选项进行设置,在 Live Sass Compiler
中配置 format
参数。
注:dart sass
只反对 expanded
和compressed
。
sass --watch style.scss:style.css --style compressed
:nested
nested
是 scss
默认的输入格局,选择器与属性等独自占用一行,缩进量与 scss
文件中统一,每行的缩进量反映了其在嵌套规定内的层数。
#main {
color: #fff;
background-color: #000; }
#main p {width: 10em;}
.p {
font-size: 10em;
font-weight: bold;
text-decoration: underline; }
:expanded
expanded
输入像是咱们平时手写的款式,选择器、属性等各占用一行,属性依据选择器缩进,而选择器不做任何缩进。
#main {
color: #fff;
background-color: #000;
}
#main p {width: 10em;}
.p {
font-size: 10em;
font-weight: bold;
text-decoration: underline;
}
:compact
compact
会将每条 css
规定演绎为一行。嵌套过的选择器在输入时没有空行,不嵌套的选择器会输入空白行作为分隔符。
#main {color: #fff; background-color: #000;}
#main p {width: 10em;}
.p {font-size: 10em; font-weight: bold; text-decoration: underline;}
:compressed
compressed
会删除所有无意义的空格、空白行、以及正文,力求将文件体积压缩到最小,同时也会做出其余调整,比方会主动替换占用空间最小的色彩表达方式。
#main{color:#fff;background-color:#000}#main p{width:10em}.p{font-size:10em;font-weight:bold;text-decoration:underline}
语法嵌套规定
选择器嵌套
css
中反复写选择器是十分宜人的。尤其是 html
构造嵌套十分深的时候,scss
的选择器嵌套能够防止反复输出父选择器,能够无效的进步开发效率,缩小款式笼罩可能造成的异样问题。这也是咱们最罕用的性能。很多人用 scss
就只用了这个性能,而后感觉本人会了🤜🤜。
这个是失常的 css
构造
.container {
width: 1200px;
margin: 0 auto;
}
.container .header .img {
width: 100px;
height: 60px;
}
编译成 scss
的样子,子元素向父元素外部嵌套了。
.container {
width: 1200px;
margin: 0 auto;
.header {
.img {
width: 100px;
height: 60px;
}
}
}
属性嵌套
有些 css
属性遵循雷同的命名空间 (雷同的结尾),比方 font-family
,font-size
,font-weight
都以 font
作为属性的命名空间。为了便于管理这样的属性,也为了防止反复输出。(这个编辑器提醒有点不太现实……,不是很好用)。
.container {
font: {
family: fantasy;
size: 30em;
weight: bold;
}
}
编译成css
.container {
font-family: fantasy;
font-size: 30em;
font-weight: bold;
}
命名空间也能够蕴含本人的属性值
.container {
color: red {adjust: fantasy;}
}
编译成css
.container {
color: red;
color-adjust: fantasy;
}
父选择器 &
在嵌套 css
规定时,有时会须要应用嵌套外层的父选择器,例如,当给某个元素设定 hover
款式时,能够用 &
代表嵌套规定外层的父选择器,scss
在编译时会把 &
替换成父选择器名。
案例外面的 &
示意的就是父级 a
选择器
.container {
a {
color: #333;
&:hover {
text-decoration: underline;
color: #f00;
}
}
}
转化成scss
.container a {color:#333;}
.container a:hover {
text-decoration:underline;
color:#F00;
}
换个思路,也能够应用 &
进行选择器名称拼接。
.main {
color: black;
&-sidebar {border: 1px solid;}
}
转化成css
.main {color: black;}
.main-sidebar {border: 1px solid;}
Scss 的两种正文
多行正文/* ... */
多行正文会编译到 .css
文件中,compressed
(压缩)模式下除外,将 !
作为多行正文的第一个字符示意在压缩输入模式下也保留这条正文,通常用于增加版权信息。
/*!
* 我是
* 多行
* 正文
*/
body {color: black;}
编译成css
/*!
* 我是
* 多行
* 正文
*/body{color:#000}
单行正文//
单行正文不会编译到 .css
文件
// 我是单行正文
body {color: black;}
编译成css
body {color: black;}
变量
应用
原生 css
中的变量,应用 -- 变量名: 变量值
定义,var(-- 变量名)
进行应用。
:root {--color: #F00;}
p {color: var(--color);
}
scss
中的变量,以美元符号 $
结尾,赋值办法与 css
属性的写法一样。
$color:#F00;
p {color: $color;}
转行成css
p {color: #F00;}
5 条变量规定
下文的 mixin
和function
命名也遵循 1234
条规定:
- 变量以美元符号
$
结尾,前面跟变量名; - 变量名是不以数字结尾的可蕴含字母、数字、下划线、横线(连接符);
- 通过连接符
-
与下划线_
定义的同名变量为同一变量; - 变量肯定要先定义,后应用;
- 写法同
css
,即变量名和值之间用冒号:
分隔;
2 种变量作用域
-
变量作用域分为 全局变量域 和局部变量域:
- 全局变量:申明在最外层的变量,可在任何中央应用;
- 局部变量:嵌套规定内定义的变量只能在嵌套规定内应用。
- 将局部变量转换为全局变量能够增加
!global
申明。
$color: red;
.container {
$height: 500px;
$font-size: 16px !global;
font-size: $font-size;
color: $color;
height: $height;
}
.footer {
/**$font-size 应用!global 申明成全局变量了 */
font-size: $font-size;
/**
* Error: Undefined variable.
* $height 是.container 下的局部变量,无奈在.footer 上面编译
*/
height:$height;
}
编译成css
.container {
font-size: 16px;
color: red;
height: 500px;
}
.footer {
/**$font-size 应用!global 申明成全局变量了 */
font-size: 16px;
}
7 种次要的数据类型
scss
反对 7
种次要的数据类型:
- 数字,
1rem、2vh、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)
;
官网中把 Function
也当作一种类型,点击原文理解。
$layer-index: 10;
$border-width: 3px;
$font-weight: bold;
$font-base-family: "Open Sans", Helvetica, Sans-Serif;
$block-base-padding: 6px 10px 6px 10px;
$top-bg-color: rgba(255, 147, 29, 0.6);
$blank-mode: true;
$var: null;
$fonts: (
serif: "Helvetica Neue",
monospace: "Consolas",
);
.container {
font-family: $font-base-family;
font-size: $font-size;
padding: $block-base-padding;
@if $blank-mode {background-color: #000;} @else {background-color: #fff;}
content: type-of($var);
content: length($var);
color: $top-bg-color;
}
// 如果列表中蕴含空值,则生成的 CSS 中将疏忽该空值。.wrap {font: 18px $font-weight map-get($fonts, "sans");
}
编译成css
.container {
font-family: "Open Sans", Helvetica, Sans-Serif;
font-size: 16px;
padding: 6px 10px 6px 10px;
background-color: #000;
content: null;
content: 1;
color: rgba(255, 147, 29, 0.6);
}
.wrap {font: 18px bold; // 如果列表中蕴含空值,则生成的 CSS 中将疏忽该空值。}
scss
属性也反对其余值,比方 Unicode
字符集,或!important
申明。然而scss
不会非凡看待这些属性值,一律视为无引号字符串。
$color:red;
.container {color:$color !important;}
编译成css
.container {color: red !important;}
!default
能够在变量的结尾增加 !default
来给变量设置默认值,有点相似 Javascript
的逻辑运算符 let content=content || "Second content"
。留神,变量是 null
时将视为未被 !default
赋值。
$content: "First content";
// 如果 $content 之前没定义就应用如下的默认值
$content: "Second content" !default;
#main {content: $content;}
编译成css
#main {content: "First content";}
圆括号
圆括号 ()
能够用来影响运算的程序,和数学中的成果是统一的。
运算符
相等运算 ==
和不相等运算!=
。所有数据类型均反对 ==
和!=
,另外,每种数据类型也有其各自反对的运算形式。
$theme:"blue";
.container {
@if $theme=="blue" {background-color: red;}
@else {background-color: blue;}
}
.container {
@if $theme !="blue" {background-color: red;}
@else {background-color: blue;}
}
编译为css
.container {background-color: red;}
.container {background-color: blue;}
关系运算符
四个关系运算符< > >= <=
$theme:3;
.container {
@if $theme >= 5 {background-color: red;}
@else {background-color: blue;}
}
编译为css
.container {background-color: blue;}
布尔运行符
三个布尔运算符and or not
$width: 100;
$height: 200;
$last: false;
div {
@if $width>50 and $height<300 {font-size: 16px;} @else {font-size: 14px;}
@if not $last {border-color: red;} @else {border-color: blue;}
@if $width>500 or $height<300{line-height: 20px;} @else {line-height: 50px;}
}
编译为css
div {
font-size: 16px;
border-color: red;
line-height: 20px;
}div {
font-size: 16px;
border-color: red;
}
数字操作符
+ - * / %
/* 纯数字与百分号或单位运算时会主动转化成相应的百分比与单位值 */
.container {
/* ================== + 运算 ===================== */
width: 50 + 20;
width: 50 + 20%;
width: 50% + 20%;
width: 10pt + 20px;
width: 10pt + 20;
/* ================== - 运算 ===================== */
height: 50 - 20;
height: 10 - 20%;
height: 50pt - 20px;
/* ================== * 运算 ===================== */
height: 50 * 30;
height: 10 * 30%;
height: 50 * 2px;
height: 50pt * 4;
/* ==================/ 运算 (除完后最多只能保留一种单位)===================== */
$width: 100px;
width: 10/5;
width: 10px / 5px;
width: 10px / 20;
width: ($width/2); // 应用变量与括号
height: (500px/2); // 应用了括号
/* ==================% 求余运算 ===================== */
width: 10 % 3;
width: 50px % 7;
width: 50% % 7;
}
编译成css
/* 纯数字与百分号或单位运算时会主动转化成相应的百分比与单位值 */
.container {
/* ================== + 运算 ===================== */
width: 70;
width: 70%;
width: 70%;
width: 25pt;
width: 30pt;
/* ================== - 运算 ===================== */
height: 30;
height: -10%;
height: 35pt;
/* ================== * 运算 ===================== */
height: 1500;
height: 300%;
height: 100px;
height: 200pt;
/* ==================/ 运算 (除完后最多只能保留一种单位)===================== */
width: 10/5;
width: 10px/5px;
width: 10px/20;
width: 50px;
height: 250px;
/* ==================% 运算 ===================== */
width: 1;
width: 1px;
width: 1%;
}
/
在 css
中有分隔数字的用处,在 scss
中,以下三种状况会进行除法运算:
- 如果值或值的一部分,是变量或者函数的返回值;
- 如果值被圆括号包裹;
- 如果值是算数表达式的一部分。
$width: 1000px;
div {
font: 16px/30px Arial, Helvetica, sans-serif; // 不运算
width: ($width/2); // 应用变量与括号
width: (#{$width}/2); // 应用 #{} 插值语句将变量包裹,防止运算。z-index: round(10)/2; // 应用了函数
height: (500px/2); // 应用了括号
margin-left: 5px + 8px/2px; // 应用了 + 表达式
}
编译成css
div {
font: 16px/30px Arial, Helvetica, sans-serif;
width: 500px;
width: 1000px/2;
z-index: 5;
height: 250px;
margin-left: 9px;
}
如果须要应用变量,同时又要确保 /
不做除法运算而是残缺地编译到 css
文件中,只须要用 #{}
插值语句将变量包裹。
字符串运算
+
可用于连贯字符串;- 如果有引号字符串(位于 + 左侧)连贯无引号字符串,运算后果是有引号的;
- 无引号字符串(位于 + 左侧)连贯有引号字符串,运算后果则没有引号。
.container {
content: "Foo" + Bar;
font-family: sans- + "serif";
}
编译为css
.container {
content: "Foo Bar";
font-family: sans-serif;
}
插值语句
文章下面有讲到插值语句,这里来解释一下。\
通过 #{}
插值语句能够在选择器、属性名、正文中应用变量,应用 #{}
插值语句将变量包裹起来即可,和 js
中的模板字符串很像。
$font-size: 12px;
$line-height: 30px;
$class-name: danger;
$attr: color;
$author: "福大命大";
p {font: #{$font-size}/#{$line-height} Arial Helvetica, sans-serif;
}
/*
* 这是文件的阐明局部
* @author: #{$author}
*/
a.#{$class-name} {border-#{$attr}: #f00;
}
编译成css
p {font: 12px/30px Arial Helvetica, sans-serif;}
/*
* 这是文件的阐明局部
* @author: 福大命大
*/
a.danger {border-color: #f00;}
流程管制
sass
中流程管制蕴含四类,也是咱们在 js
中常见的@if、@for、@each、@while
。
@if
@if
语法和 js
相似,根本格局是@if...@else if...@else
。
应用
$theme:3;
.container {
@if $theme >= 5 {background-color: red;}
@else {background-color: blue;}
}
编译为css
.container {background-color: blue;}
案例
这里已一个利用 mixin
和if
封装一个三角形生成,mixin
常识前面又讲到。
@mixin triangle($direction:top, $size:30px, $border-color:black) {
width: 0px;
height: 0px;
display: inline-block;
border-width: $size;
border-#{$direction}-width: 0;
@if ($direction==top) {
border-color: transparent transparent $border-color transparent;
border-style: dashed dashed solid dashed;
}
@else if($direction==right) {
border-color: transparent transparent transparent $border-color;
border-style: dashed dashed dashed solid;
}
@else if($direction==bottom) {
border-color: $border-color transparent transparent transparent;
border-style: solid dashed dashed dashed;
}
@else if($direction==left) {
border-color: transparent $border-color transparent transparent;
border-style: dashed solid dashed dashed;
}
}
.p0 {@include triangle($size:50px);
}
.p1 {@include triangle(right, 50px, red);
}
.p2 {@include triangle(bottom, 50px, blue);
}
.p3 {@include triangle(left, 50px, green);
}
编译为
.p0 {
width: 0px;
height: 0px;
display: inline-block;
border-width: 50px;
border-top-width: 0;
border-color: transparent transparent black transparent;
border-style: dashed dashed solid dashed;
}
.p1 {
width: 0px;
height: 0px;
display: inline-block;
border-width: 50px;
border-right-width: 0;
border-color: transparent transparent transparent red;
border-style: dashed dashed dashed solid;
}
.p2 {
width: 0px;
height: 0px;
display: inline-block;
border-width: 50px;
border-bottom-width: 0;
border-color: blue transparent transparent transparent;
border-style: solid dashed dashed dashed;
}
.p3 {
width: 0px;
height: 0px;
display: inline-block;
border-width: 50px;
border-left-width: 0;
border-color: transparent green transparent transparent;
border-style: dashed solid dashed dashed;
}
@for
for
在条件范畴内反复操作,这个指令蕴含两种格局:
@for $var from <start> through <end>
;@for $var from <start> to <end>
。
两者区别在于 through
与 to
的含意:
- 应用
through
时,条件范畴蕴含<start>
与<end>
的值; - 应用
to
时条件范畴只蕴含<start>
的值不蕴含<end>
的值; $var
能够是任何变量,比方$i
,<start>
和<end>
必须是整数值。
@for $i from 1 to 3 {#loading span:nth-child(#{$i}) {width: 20 * ($i - 1) + px;
}
}
编译为
#loading span:nth-child(1) {width: 0px;}
#loading span:nth-child(2) {width: 20px;}
如果把 to
换成through
#loading span:nth-child(1) {width: 0px;}
#loading span:nth-child(2) {width: 20px;}
#loading span:nth-child(3) {width: 40px;}
@each
@each
指令的格局是 @each $var in $list
, $var
能够是任何变量名,比方 $length
或者$name
,而$list
是一连串的值,也就是值列表。
$color-list:red green blue turquoise darkmagenta;
@each $color in $color-list {$index: index($color-list, $color);
.p#{$index - 1} {background-color: $color;}
}
编译为
.p0 {background-color: red;}
.p1 {background-color: green;}
.p2 {background-color: blue;}
.p3 {background-color: turquoise;}
.p4 {background-color: darkmagenta;}
@while
@while
指令循环输入直到表达式返回后果为 false
。这样能够实现比@for
更简单的循环。
比方,能够借此生成栅格化布局。
$column:12;
@while $column>0 {.col-sm-#{$column} {width: $column / 12 * 100%;}
$column:$column - 1;
}
编译为
.col-sm-12 {width: 100%;}
.col-sm-11 {width: 91.6666666667%;}
.col-sm-10 {width: 83.3333333333%;}
.col-sm-9 {width: 75%;}
.col-sm-8 {width: 66.6666666667%;}
.col-sm-7 {width: 58.3333333333%;}
.col-sm-6 {width: 50%;}
.col-sm-5 {width: 41.6666666667%;}
.col-sm-4 {width: 33.3333333333%;}
.col-sm-3 {width: 25%;}
.col-sm-2 {width: 16.6666666667%;}
.col-sm-1 {width: 8.3333333333%;}
@import
@import
算是一个比拟繁难的模块零碎。scss
拓展了 @import
的性能,容许其导入 scss
或 sass
文件。被导入的文件将合并编译到同一个 css
文件中,被导入的文件中所蕴含的变量或者混合指令 (mixin
) 都能够在导入的文件中应用。
应用
common.scss
$color:red;
index.scss
@import "common.scss";
.container {border-color: $color;}
编译成
.container {border-color: red;}
以下状况下,@import
仅作为一般的 css
语句,不会导入 scss
文件:
- 文件拓展名是
.css
; - 文件名以
http://
结尾; - 文件名是
url()
; @import
蕴含媒体查问。
@import "common.css";
@import url(common);
@import "http://xxx.com/xxx";
@import 'landscape' screen and (orientation:landscape);
scss
容许同时导入多个文件,例如同时导入 rounded-corners
与 text-shadow
两个文件,不必再独自写个import
引入。
@import "rounded-corners", "text-shadow";
导入文件也能够应用 #{}
插值语句(上面有讲,这里把它了解成 js
中模板字符串就行)动静导入,但不是通过变量动静导入 scss
文件,只能作用于 css
的 url()
导入形式
$family: unquote("Droid+Sans");
编译为
@Partials
如果须要导入 scss
或者 sass
文件,但又不心愿将其编译为 css
,只须要在文件名前增加下划线,这样会通知 scss
不要编译这些文件。
留神:
- 导入语句中却不须要增加下划线;
- 不能够同时存在增加下划线与未增加下划线的同名文件,增加下划线的文件将会被疏忽。
_common.scss
$color:red;
index.scss
@import "common.scss";
.container {border-color: $color;}
编译为
.container {border-color: red;}
_common.scss
文件不会编译成 _common.css
文件。
Partials
次要是用来定义公共款式的,专门用于被其余的 scss
文件 import
进行应用的。
嵌套 @import
大多数状况下,个别在文件的最外层(不在嵌套规定内)应用@import
,其实,也能够将@import
嵌套进内层选择器或者 @media
中,与平时的用法成果雷同,只是这样导入的款式只能呈现在嵌套的层中,存在作用域。
common.scss
.example {color: red;}
index.scss
#main {@import "example";}
被编译成
#main .example {color: red;}
留神:@import
不能嵌套应用在控制指令或混入中(带有 @
符号的叫指令)。
@media 媒体查问加强
scss
中,@media
指令与 css
中用法一样,只是减少了一点额定的性能,容许在 css
规定中嵌套。如果 @media
嵌套在 css
规定内,编译时,@media
将被编译到文件的最外层,蕴含嵌套的父选择器。这个让 @media
不便不少,不须要反复写选择器,也不会打乱 css
的书写流程。
应用
.sidebar {
width: 300px;
@media screen and (orientation: landscape) {
width: 500px;
.item {height: auto;}
}
}
编译为
.sidebar {width: 300px;}
@media screen and (orientation: landscape) {
.sidebar {width: 500px;}
.sidebar .item {height: auto;}
}
嵌套
@media
容许相互嵌套应用,编译时,scss
主动增加 and
@media screen {
.sidebar {@media (orientation: landscape) {width: 500px;}
}
}
编译为
@media screen and (orientation: landscape) {
.sidebar {width: 500px;}
}
应用插值
能够应用变量,函数,以及运算符代替条件的名称或者值。
$media: screen;
$feature: -webkit-min-device-pixel-ratio;
$value: 1.5;
@media #{$media} and ($feature: $value) {
.sidebar {width: 500px;}
}
编译为
@media screen and (-webkit-min-device-pixel-ratio: 1.5) {
.sidebar {width: 500px;}
}
@mixin
混合指令(Mixin
)用于定义可重复使用的款式。混合指令能够蕴含所有的 css
规定,绝大部分 scss
规定,甚至能够通过参数性能引入变量,输入多样化的款式。
留神:函数命名和变量命名规定统一。
应用
@mixin mixin-name() {/* css 申明 */}
// 应用
@include mixin-name;
规范模式
// 定义一个区块根本的款式
@mixin block {
width: 96%;
margin-left: 2%;
border-radius: 8px;
border: 1px #f6f6f6 solid;
}
// 应用混入
.container {
.block {@include block;}
}
编译为
.container .block {
width: 96%;
margin-left: 2%;
border-radius: 8px;
border: 1px #f6f6f6 solid;
}
嵌入选择器
@mixin
外面再嵌套一层
@mixin warning-text {
font-size: 12px;
.warn-text {color: rgb(255, 253, 123);
line-height: 180%;
}
}
.container {@include warning-text;}
编译为
.container {font-size: 12px;}
.container .warn-text {
color: #fffd7b;
line-height: 180%;
}
单参数
// 定义 flex 布局元素纵轴的排列形式
@mixin flex-align($aitem) {align-items: $aitem;}
// 只有一个参数,间接传递参数
.container {@include flex-align(center);
}
编译为
.container {align-items: center;}
多参数
// 定义块元素内边距
@mixin block-padding($top, $right, $bottom, $left) {
padding-top: $top;
padding-right: $right;
padding-bottom: $bottom;
padding-left: $left;
}
// 依照参数程序赋值
.container1 {@include block-padding(10px, 20px, 30px, 40px);
}
// 可指定参数赋值
.container2 {@include block-padding($left: 20px, $top: 10px, $bottom: 10px, $right: 30px);
}
// 可指定参数赋值,然而必须指定 4 个值,不能缺失
.container3 {@include block-padding($left: 10px, $top: 10px, $bottom: 0, $right: 0);
}
编译为
.container1 {
padding-top: 10px;
padding-right: 20px;
padding-bottom: 30px;
padding-left: 40px;
}
.container2 {
padding-top: 10px;
padding-right: 30px;
padding-bottom: 10px;
padding-left: 20px;
}
.container3 {
padding-top: 10px;
padding-right: 0;
padding-bottom: 0;
padding-left: 10px;
}
指定默认值
// 定义块元素内边距,参数指定默认值
@mixin block-padding($top:0, $right:0, $bottom:0, $left:0) {
padding-top: $top;
padding-right: $right;
padding-bottom: $bottom;
padding-left: $left;
}
// 可指定参数赋值
.container {
/** 不带参数 */
@include block-padding;
/** 按程序指定参数值 */
@include block-padding(10px,20px);
/** 给指定参数指定值 */
@include block-padding($left: 10px, $top: 20px)
}
编译为
.container {
/** 不带参数 */
padding-top: 0;
padding-right: 0;
padding-bottom: 0;
padding-left: 0;
/** 按程序指定参数值 */
padding-top: 10px;
padding-right: 20px;
padding-bottom: 0;
padding-left: 0;
/** 给指定参数指定值 */
padding-top: 20px;
padding-right: 0;
padding-bottom: 0;
padding-left: 10px;
}
可变参数
应用 ...
解决参数不固定的状况,相似于 js
中的函数的残余参数
@mixin linear-gradient($direction, $gradients...) {background-color: nth($gradients, 1);
background-image: linear-gradient($direction, $gradients);
}
.table-data {@include linear-gradient(to right, #F00, orange, yellow);
}
编译为
.table-data {
background-color: #F00;
background-image: linear-gradient(to right, #F00, orange, yellow);
}
总结
mixin
是能够重复使用的一组css
申明,有助于缩小反复代码,只需申明一次,就可在文件中援用;- 混合指令能够蕴含所有的
css
规定,绝大部分scss
规定,能够传递参数,输入多样化的款式; - 应用参数时倡议加上默认值;
@import
导入部分模块化款式(相似性能、同一组件);@minix
定义的是可重复使用的款式
@function
@function
用于封装简单的操作,能够很容易地以一种可读的形式形象出通用公式和行为,函数提供返回值,罕用来做计算方面的工作。
应用
留神:函数命名和变量命名规定统一。
@function square($base) {@return $base * $base * 1px;}
.sidebar {
float: left;
margin-left: square(4);
}
编译为
.sidebar {
float: left;
margin-left: 16px;
}
可选参数
默认值能够是任何表达式,它们甚至能够援用后面的参数!
//change-color 和 hue 是内置办法
//hue 返回 $color 的色彩为 0 到 360 度之间的一个数字。//change-color 用于设置色彩的属性
@function invert($color, $amount: 100%) {//@error hue($color); 调试 210deg
$inverse: change-color($color, $hue: hue($color) + 180);
@return mix($inverse, $color, $amount);
}
$primary-color: #036;
.header {background-color: invert($primary-color, 80%);
}
编译为
.header {background-color: #523314;}
指定参数
$primary-color: #036;
.banner {
//scale-color Fluidly scales one or more properties of .$color
background-color: $primary-color;
color: scale-color($primary-color, $lightness: +40%);
}
编译为
.banner {
background-color: #036;
color: #0a85ff;
}
可变参数
参数列表还可用于采纳任意关键字参数,meta.keywords()
函数采纳参数列表
@function sum($numbers...) {
$sum: 0;
@each $number in $numbers {$sum: $sum + $number;}
@return $sum;
}
$widths: 50px, 30px, 100px;
.micro {width: sum($widths...);
}
编译为
.micro {width: 180px;}
@return
@return
只容许在 @function
内应用,和 js
一样,遇到 return
就会返回。
@function red() {
$is: true;
@if $is {@return 'is';}
@return red;
}
.con{color: red();
}
编译为
.con {color: "is";}
总结:@function
和 @mixin
参数的应用形式没啥区别;@function
用来计算,@mixin
用来封装款式,@import
用来抽离他们为一个模块。
@extend 继承
应用
咱们以 elementUI
的el-button
组件为例,能够应用 @extend
继承曾经存在的款式,原理是应用逗号选择器。
// # id 选择器一样的
.button {
display: inline-block;
margin-bottom: 0;
font-weight: normal;
text-align: center;
white-space: nowrap;
vertical-align: middle;
cursor: pointer;
background-image: none;
border: 1px solid transparent;
padding: 6px 12px;
font-size: 14px;
line-height: 1.42857143;
border-radius: 4px;
user-select: none;
}
.btn-default {
@extend .button;
color: #333;
background-color: #fff;
border-color: #ccc;
}
.btn-danger {
@extend .button;
color: #fff;
background-color: #d9534f;
border-color: #d43f3a;
}
编译成
.button, .btn-danger, .btn-default {
display: inline-block;
margin-bottom: 0;
font-weight: normal;
text-align: center;
white-space: nowrap;
vertical-align: middle;
cursor: pointer;
background-image: none;
border: 1px solid transparent;
padding: 6px 12px;
font-size: 14px;
line-height: 1.42857143;
border-radius: 4px;
user-select: none;
}
.btn-default {
color: #333;
background-color: #fff;
border-color: #ccc;
}
.btn-danger {
color: #fff;
background-color: #d9534f;
border-color: #d43f3a;
}
能够应用多个 @extend
.alert {
padding: 15px;
margin-bottom: 20px;
border: 1px solid transparent;
border-radius: 4px;
font-size: 12px;
}
.important {
font-weight: bold;
font-size: 14px;
}
.alert-danger {
@extend .alert;
@extend .important;
color: #a94442;
background-color: #f2dede;
border-color: #ebccd1;
}
编译为
.alert, .alert-danger {
padding: 15px;
margin-bottom: 20px;
border: 1px solid transparent;
border-radius: 4px;
font-size: 12px;
}
.important, .alert-danger {
font-weight: bold;
font-size: 14px;
}
.alert-danger {
color: #a94442;
background-color: #f2dede;
border-color: #ebccd1;
}
多层继承
@extend
能够多层继承,列如:.alert-danger
继承自 .important
,.important
又继承自.alert
。
.alert {
padding: 15px;
margin-bottom: 20px;
border: 1px solid transparent;
border-radius: 4px;
font-size: 12px;
}
.important {
@extend .alert;
font-weight: bold;
font-size: 14px;
}
.alert-danger {
@extend .important;
color: #a94442;
background-color: #f2dede;
border-color: #ebccd1;
}
编译为
.alert, .important, .alert-danger {
padding: 15px;
margin-bottom: 20px;
border: 1px solid transparent;
border-radius: 4px;
font-size: 12px;
}
.important, .alert-danger {
font-weight: bold;
font-size: 14px;
}
.alert-danger {
color: #a94442;
background-color: #f2dede;
border-color: #ebccd1;
}
占位符选择器
占位符选择器 %
,与罕用的id
与 class
选择器写法类似,只是 #
或 .
替换成了 %
,占位符选择器必须通过 @extend
指令调用。\
还是下面的例子,这里应用占位符选择器操作
.button %base {
display: inline-block;
margin-bottom: 0;
font-weight: normal;
text-align: center;
white-space: nowrap;
vertical-align: middle;
cursor: pointer;
background-image: none;
border: 1px solid transparent;
padding: 6px 12px;
font-size: 14px;
line-height: 1.42857143;
border-radius: 4px;
user-select: none;
}
.btn-default {
@extend %base;
color: #333;
background-color: #fff;
border-color: #ccc;
}
.btn-danger {
@extend %base;
color: #fff;
background-color: #d9534f;
border-color: #d43f3a;
}
成果和下面的类选择器一样,然而,他有个有长处,占位符选择器 %
所属的款式未应用时,不会被编译到 css
文件中,算是一个小优化吧。
.button .btn-danger, .button .btn-default {
display: inline-block;
margin-bottom: 0;
font-weight: normal;
text-align: center;
white-space: nowrap;
vertical-align: middle;
cursor: pointer;
background-image: none;
border: 1px solid transparent;
padding: 6px 12px;
font-size: 14px;
line-height: 1.42857143;
border-radius: 4px;
user-select: none;
}
.btn-default {
color: #333;
background-color: #fff;
border-color: #ccc;
}
.btn-danger {
color: #fff;
background-color: #d9534f;
border-color: #d43f3a;
}
@use
存在兼容性问题,仅在 Dart Sass 1.23.0
以上无效,官网文档有兼容性介绍。
scss
真正意义上的模块化,能够从其它 scss
样式表中加载 mixin
、function
和变量
,并将来自多个样式表的 css
组合在一起。scss
还提供了很多内置模块,咱们能够通过 @use
应用。
@import 毛病
- 多处导入,存在款式反复加载。
- 因为没有命名空间,为了防止撞名,不敢应用简写的
classname
,因而起名总是须要留神。 - 没有公有函数的概念,款式齐全裸露在应用
import
的中央,这对ui
库不够敌对。
应用
src/_corners.scss
$radius: 3px;
@mixin rounded {border-radius: $radius;}
index.scss
@use "src/corners";
.button {
@include corners.rounded;
padding: 5px + corners.$radius;
}
命名空间
src/_corners.scss
$radius: 3px;
@mixin rounded {border-radius: $radius;}
index.scss
@use "src/corners" as c;
.button {
@include c.rounded;
padding: 5px + c.$radius;
}
编译为
.button {
border-radius: 3px;
padding: 8px;
}
as*
应用as*
,那么这一模块就处于全局命名空间。
src/_corners.scss
$radius: 3px;
@mixin rounded {border-radius: $radius;}
index.scss
@use "src/corners" as *;
.button {
@include rounded;
padding: 5px + $radius;
}
编译为
.button {
border-radius: 3px;
padding: 8px;
}
公有模块
应用 scss
能够轻松地定义公有成员,公有成员命名以 -
或结尾。
src/_corners.scss
$-radius: 3px;
@mixin rounded {border-radius: $-radius;}
index.scss
@use "src/corners";
.button {
@include corners.rounded;
// Error: Private members can't be accessed from outside their modules
padding: 5px + corners.$-radius;
}
@forward
@forward
语句能够引入另一个模块的所有变量、mixins
和函数,将它们间接作为以后模块的 API
裸露进来,不会真的在以后模块减少代码。不同于 @use
,@forward
不能给变量增加命名空间。
用法
留神,此时生成的 bootstrap.css
文件中,是不蕴含 functions
、variables
、mixins
代码的,也不能间接在 bootstrap.scss
文件中应用这些模块。而是须要在另一个文件中 @import 'bootstrap'
或者 @use bootstrap
模块,再去应用这些办法。bootstrap.scss
文件相似于一个传输中转站,把上下游的成员变量无缝连接起来。
/* bootstrap.scss */
@forward"functions";
@forward"variables";
@forward"mixins";
留神,间接写在上游模块的失常的款式依然会被 @forward
进来。见下例:
a.scss
@mixin rounded {border-radius: 100px;}
footer {height: 1px;}
b.scss
$radius: 3px;
c.scss
@forward "a";
@forward "b";
index.scss
@import "c.scss";
.button {
@include rounded;
padding: $radius;
}
编译为
footer {height: 1px;}
.button {
border-radius: 100px;
padding: 3px;
}
show/ hide
通过管制 show
和 hide
,能够决定模块中的哪些成员对引入后的模板可见。对暗藏的变量,在上游文件中不能够应用,相当于模块公有成员。
c.scss
@forward "a" show rounded;
@forward "b" hide $radius;
index.css
@import "c.scss";
.button {
@include rounded;
padding: $radius;
}
// Error: Undefined variable. padding: $radius;
应用 as * 号为子模块增加前缀
大多数状况下,一个款式库会存在一个入口文件 index.scss
,而后在index.scss
中引入其余的子文件。这种构造相似于一个多合一模块。那么,如果要在某一文件中 @forward
多个子模块,就能够应用 as <prefix>-*
语句,为子模块下的成员主动带上前缀以辨别。
c.scss
@forward "a" as mixin-*;
@forward "b" as var-*;
index.css
@import "c.scss";
.button {
@include mixin-rounded;
padding: $var-radius;
}
很多内置的办法就是这样应用的,嘿嘿!
@at-root
@at-root
用来跳出嵌套,在多级嵌套时比拟罕用,蕴含 without
和with
。
用法
// 没有跳出
.parent-1 {
color:#f00;
.child {width:100px;}
}
// 单个选择器跳出
.parent-2 {
color:#f00;
@at-root .child {width:200px;}
}
// 多个选择器跳出
.parent-3 {
background:#f00;
@at-root {
.child1 {width:300px;}
.child2 {width:400px;}
}
}
编译为
.parent-1 {color: #f00;}
.parent-1 .child {width: 100px;}
.parent-2 {color: #f00;}
.child {width: 200px;}
.parent-3 {background: #f00;}
.child1 {width: 300px;}
.child2 {width: 400px;}
@without 和 with
默认 @at-root
只会跳出选择器嵌套,而不能跳出 @media
或@support
,如果要跳出这两种,则需应用 @at-root (without: media)
或@at-root (without: support)
,@at-root
的关键词有四个:
all
示意所有;rule
示意惯例css
选择器;media
示意media
;support
示意support
(@support
次要是用于检测浏览器是否反对css
的某个属性)。
咱们默认的 @at-root
是@at-root (without:rule)
/* 跳出父级元素嵌套 */
@media print {
.parent1{
color:#f00;
@at-root .child1 {width:200px;}
}
}
/* 跳出 media 嵌套,父级无效 */
@media print {
.parent2{
color:#f00;
@at-root (without: media) {
.child2 {width:200px;}
}
}
}
/* 跳出 media 和父级 */
@media print {
.parent3{
color:#f00;
@at-root (without: all) {
.child3 {width:200px;}
}
}
}
编译成
/* 跳出父级元素嵌套 */
@media print {
.parent1 {color: #f00;}
.child1 {width: 200px;}
}
/* 跳出 media 嵌套,父级无效 */
@media print {
.parent2 {color: #f00;}
}
.parent2 .child2 {width: 200px;}
/* 跳出 media 和父级 */
@media print {
.parent3 {color: #f00;}
}
.child3 {width: 200px;}
@at-root 与 & 配合应用
.child{
@at-root .parent &{color:#f00;}
}
编译成
.parent .child {color: #f00;}
利用于 @keyframe
.demo {
animation: motion 3s infinite;
@at-root {@keyframes motion {}
}
}
编译成
.demo {animation: motion 3s infinite;}
@keyframes motion {}
Scss 内置扩大
scss
内置扩大分为 color list map math meta selector string
等,扩大也就是 scss
内置的一些function
,每个模块下内容比拟多,这里用一些罕用的进行举例。
内置函数能够应用 @use
模块化引入,也能够间接应用他提供的全局函数名调用,以下两种形式是一样的。
@use 'sass:list';
p {color: nth($list: red blue green, $n: 2); // blue
color: list.nth($list: red blue green, $n: 2); // blue
}
color
scss
蕴含很多操作色彩的函数。例如 lighten()
与 darken()
可用于调亮或调暗色彩,opacify()
使色彩透明度缩小,transparent()
使色彩透明度减少,mix()
用来混合两种色彩。
.p1 {
// 让色彩变亮
color:scale-color(#5c7a29, $lightness: +30%);
}
.p2 {
// 让色彩变暗
color:scale-color(#5c7a29, $lightness: -15%);
}
.p3 {
// 升高色彩透明度
color:scale-color(#5c7a29, $alpha: -40%);
}
编译为
.p1 {color: #95c249;}
.p2 {color: #4e6823;}
.p3 {color: rgba(92, 122, 41, 0.6);
}
String
scss
有许多解决字符串的函数,比方向字符串增加引号的 quote()
、获取字符串长度的string-length()
和将内容插入字符串给定地位的string-insert()
。
p {
&:after {content: quote(这是外面的内容);
}
background-color: unquote($string: "#F00");
z-index:str-length("scss 学习");
}
编译为
p {
background-color: #F00;
z-index: 6;
}
p:after {content: "这是外面的内容";}
Math
数值函数解决数值计算,例如:percentage()
将无单元的数值转换为百分比,round()
将数字四舍五入为最靠近的整数,min()
和 max()
获取几个数字中的最小值或最大值,random()
返回一个随机数。
p {z-index: abs(-15); // 15
z-index: ceil(5.8); //6
z-index: max(5, 1, 6, 8, 3); //8
opacity: random(); // 随机 0-1}
编译为
p {
z-index: 15;
z-index: 6;
z-index: max(5, 1, 6, 8, 3);
opacity: 0.8636254167;
}
List
List
函数操作 List
,length()
返回列表长度,nth()
返回列表中的特定项,join()
将两个列表连贯在一起,append()
在列表开端增加一个值。
p {z-index: length(12px); //1
z-index: length(12px 5px 8px); //3
z-index: index(a b c d, c); //3
padding: append(10px 20px, 30px); // 10px 20px 30px
color: nth($list: red blue green, $n: 2); // blue
}
编译为
p {
z-index: 1;
z-index: 3;
z-index: 3;
padding: 10px 20px 30px;
color: blue;
}
Map
Map
函数操作 Map
,map-get()
依据键值获取 map
中的对应值,map-merge()
来将两个 map
合并成一个新的 map
,map-values()
映射中的所有值。
$font-sizes: ("small": 12px, "normal": 18px, "large": 24px);
$padding:(top:10px, right:20px, bottom:10px, left:30px);
p {font-size: map-get($font-sizes, "normal"); //18px
@if map-has-key($padding, "right") {padding-right: map-get($padding, "right");
}
&:after {content: map-keys($font-sizes) + ""+ map-values($padding) +"";
}
}
编译为
p {
font-size: 18px;
padding-right: 20px;
}
p:after {content: '"small", "normal", "large" 10px, 20px, 10px, 30px';}
selector
选择符相干函数可对抉择 css
进行一些相应的操作,例如:selector-append()
能够把一个选择符附加到另一个选择符,selector-unify()
将两组选择器合成一个复合选择器。
@use 'sass:selector';
@debug selector.is-superselector("a", "a"); // true
// 能够间接应用 @forward 下的前缀
@debug selector-append("a", ".disabled"); // a.disabled
@debug selector-extend("a.disabled", "a", ".link"); // a.disabled, .link.disabled
.header {content: selector-append(".a", ".b", ".c") + '';
content: selector-unify("a", ".disabled") + '';
}
编译为
.header {
content: ".a.b.c";
content: "a.disabled";
}
meta
meta
提供一个 mixin
和一些原子级别的 function
,比方应用meta.calc-args
获取办法的参数,meta.calc-name
获取办法名。
meta.load-css
meta.load-css($url,$with:())
该 mixin
能够把 $url
中css
款式全副蕴含进来。留神,$url
引入的函数,变量和 mixin
在 meta.load-css()
后的 scss
中并不能用,它只会返回编译后的 css
代码。它的第二个参数能够批改应用了 !default
的变量。
src/corners
$border-contrast: false !default;
code {
background-color: #6b717f;
color: #d2e1dd;
@if $border-contrast {border-color: #dadbdf;}
}
index.scss
@use "sass:meta";
body.dark {@include meta.load-css("src/corners", $with: ("border-contrast": true));
}
编译为
body.dark code {
background-color: #6b717f;
color: #d2e1dd;
border-color: #dadbdf;
}
function
@use "sass:meta";
@debug meta.calc-args(calc(100px + 10%)); // unquote("100px + 10%")
@debug meta.calc-args(clamp(50px, var(--width), 1000px)); // 50px, unquote("var(--width)"), 1000px
@debug meta.calc-name(calc(100px + 10%)); // "calc"
@debug meta.calc-name(clamp(50px, var(--width), 1000px)); // "clamp"
调试相干
@debug
@debug
打印表达式的值,不便调试。
$font-sizes: 10px + 20px;
$style: (color: #bdc3c7);
.container {
@debug $style;
@debug $font-sizes;
}
@error
@error
显示致命谬误
$colors: (
blue: #c0392b,
black: #2980b9
);
@function style-variation($style) {@error "Invalid color:'#{$style}'.";
@if map-has-key($colors, $style) {@return map-get($colors, $style);
}
}
.container {color: style-variation(white);
}
@warn
@warn
显示警告性倡议,会显示堆栈信息。
$colors: (
blue: #c0392b,
black: #2980b9
);
@function style-variation($style) {@warn "Invalid color:'#{$style}'.";
@if map-has-key($colors, $style) {@return map-get($colors, $style);
}
}
.container {color: style-variation(white);
}
自检函数
自检相干函数,属于内置扩大 meta
下的办法,feature-exists()
查看以后 scss
版本是否存在某个个性,variable-exists()
查看以后作用域中是否存在某个变量,mixin-exists()
查看某个 mixin
是否存在。自检函数通常用在代码的调试上,返回的是个布尔值。
$color:#F00;
@mixin padding($left:0, $top:0, $right:0, $bottom:0) {padding: $top $right $bottom $left;}
.container {@if variable-exists(color) {color: $color;}
@else {content: "$color 不存在";}
@if mixin-exists(padding) {@include padding($left: 10px, $right: 10px);
}
}
编译为
.container {
color: #F00;
padding: 0 10px 0 10px;
}
结语
看了这么久了,辛苦了,不过我也写了很久啦,大佬无妨点个赞再走吧。😁😁😁
也能够看看我的其余文章,嘿嘿嘿
🎉🎉2022 年除夕,我终于搞懂了原型和原型
🎉🎉13 道隐式类型转换面试题,让你一次爽到底
🎉🎉⌈2022⌋ JavaScript 超具体循环总结
🎉🎉云闪付小程序前端不齐全踩坑指北
🎉🎉巧用 Node.js process 暗藏我的项目重要参数