css 预处理器用一种专门的编程语言,进行 Web 页面样式设计,然后再编译成正常的 css文件,以供项目使用。css预处理器为 css增加一些编程的特性,无需考虑浏览器的兼容性问题。
最开始 css在网页中的作用只是辅助性的装饰,轻便易学是最大的需求;然而如今网站的复杂度已经不可同日而语,css种无法定义变量以及没有合理的样式复用机制,导致整体CSS样式难以维护,原生 css已经让开发者力不从心。
开发者选择了另一门更高级的语言(Ruby)来进行开发,然后编译到底层语言以便实际运行,css预处理器应运而生,扩展了css的使用场景与范围。
sass、less、stylus是三种使用最广泛的css预处理器。
sass 和 scss 其实是同一种东西,我们平时都称之为 sass,两者之间不同之处有以下两点:
sass 语法:
$font-stack: sans-serif //定义变量
$primary-color: #333 //定义变量
body
font: 100% $font-stack
color: $primary-color
scss语法:
$font-stack: sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}
编译出来的 css
body {
font: 100% sans-serif;
color: #333;
}
scss和 css写法无差别,这也是 sass后来越来越受大众喜欢原因之一。简单点说,把你现有的“.css”文件直接修改成“.scss”即可使用。
如果你在使用 Node.js,你可以利用 npm 安装 Sass:
cnpm install -g sass
注意: 这种方式安装的 sass是纯 JavaScript 实现的,运行的速度比ruby版本稍微慢一些。 但是接口是完全一致的。不用Ruby Sass的原因
sass中文文档
angular项目如何使用sass
sass实时编辑转化为css
.main p {
color: #00ff00;
width: 97%;
.redbox {
background-color: #ff0000;
color: #000000;
}
}
//编译为
.main p {
color: #00ff00;
width: 97%;
}
.main p .redbox {
background-color: #ff0000;
color: #000000;
}
.text a {
color: blue;
&:hover { color: red }
&:active{ color: blue}
}
//编译为
.text a {
color: blue;
}
.text a:hover {
color: red;
}
.text a:active {
color: blue;
}
可以看出 scss 的结构要比 css 清晰,并且写的也要更少。
变量是以 $ 开头的,可以是颜色,长度,数值,等等。
像 js 的变量一样,scss 的变量也是有作用域的,也就是说内部声明的变量是无法在外面使用的,如果想让内部的变量在外部可访问,需要在变量值后面添加 !global 声明。
$bg-color1: red; //默认定义
.btn-success {
background-color: $bg-color1;
$bg-color2: blue !global;
}
.btn{
background-color: $bg-color2;
}
//编译后
.btn-success {
background-color: red;
}
.btn {
background-color: blue;
}
将变量直接嵌入字符串,需要用#{ 变量 }
(类似 ES6 中模板字符串中的 ${ 变量 }
其实 #{} 中是可以插入任意东西的,这里只用到了插入变量,还可以插入方法等等,高级用法。
$img-path: "/assets/static/img";
.card{
background: url("#{$img-path}/card-bg.png");
}
//编译后
.card {
background: url("/assets/static/img/card-bg.png");
}
scss当前支持七种主要数据类型:
(1)数字: 如,1、 2、 13、 10px;
(2)字符串: 有引号字符串或无引号字符串,如,“foo”、 ‘bar’、 baz;
(3)颜色: 如,blue、 #04a3f9、 rgba(255,0,0,0.5);
(4)布尔型:如,true、 false;
(5)空值: 如,null;
(6)值列表: 用空格或者逗号分开,如,1.5em 1em 0 2em 、 Helvetica, Arial, sans-serif。
(7)map: 更像是一个 JSON 数据。
https://blog.csdn.net/Rayshaan/article/details/111149065
加法与减法:在Sass中,做加法运算时,数值可以带单位,但是需要运算单位相同。如果不相同就会报错,编译不通过。做减法运算是“变量”而不是“数值”的时候,要注意减号“-”前后一定要有空格
乘法:两个值单位相同时,只需要为一个数值提供单位即可。
除法:“/”在CSS中已经作为一种符号来使用了,例如我们常见的字体属性缩写font:Arial 12px/1.5em (表示字体大小12px,行高1.5em)
。因此在Sass中做除法运算的时候,如果我们直接使用“/”符号作为除号,将不会生效。因此在Sass中,如果我们想要做除法运算,我们需要在外面添加一个“小括号()”。
实际开发中,不管是加法、减法,还是乘法、除法运算,建议在外面加上小括号。这种书写方式,能够使得代码一目了然,也方便维护。
实例:
.box {
width: ((220px + 720px) - 11 * 20 ) / 12 ;
}
//编译后
.box {
width: 60px;
}
在 Sass 中可以通过加法符号“+”来对字符串进行连接。
$content: "Hello" + "" + "Sass!";
.box:before {
content: " #{$content} ";
}
//编译后
.box:before {
content: " Hello Sass! ";
}
注意:
p:before {
content: "Foo " + Bar;
font-family: sans- + "serif";
}
//编译后
p:before {
content: "Foo Bar";
font-family: sans-serif;
}
所有算数运算都支持颜色值,并且是分段运算的。也就是说,红、绿和蓝各颜色分段单独进行运算。如:
p {
color: #010203 + #040506;
}
计算公式为 01 + 04 = 05、02 + 05 = 07 和 03 + 06 = 09, 并且被合成为:
如此编译出来的 CSS 为:
p {
color: #050709;
}
初学者都常常纠结于这个问题“什么时候用混合宏,什么时候用继承,什么时候使用占位符?”其实他们各有各的优点与缺点,先来看看他们使用效果:
//使用@mixin声明混合宏(声明混入)
@mixin mt($var){
margin-top: $var;
}
//使用@include调用
.block {
@include mt(5px);
span {
display:block;
@include mt(5px);
}
}
//编译后
.block {
margin-top: 5px;
}
.block span {
display: block;
margin-top: 5px;
}
总结:混合宏不会自动合并相同的样式代码,如果在样式文件中调用同一个混合宏,会产生多个对应的样式代码,可能会造成代码的冗余,但是混合宏的优势在于可以传参数
。
个人建议:如果你的代码块中涉及到变量,建议使用混合宏来创建相同的代码块。
同样的,将上面代码中的混合宏,使用类名来表示,然后通过继承来调用:
//SCSS 继承的运用
.mt{
margin-top: 5px;
}
.block {
@extend .mt;
span {
display:block;
@extend .mt;
}
}
//编译后
.mt, .block span, .block {
margin-top: 5px;
}
.block span {
display: block;
}
总结:使用继承后,编译出来的 CSS 会将使用继承的代码块合并到一起,通过组合选择器的方式向大家展现,比如 .mt, .block, .block span, .header, .header span。这样编译出来的代码相对于混合宏来说要干净的多。但是继承不能传变量参数
。
个人建议:如果你的代码块不需要专任何变量参数,而且有一个基类已在文件中存在,那么建议使用 Sass 的继承。
最后来看占位符,将上面代码中的基类 .mt 换成 Sass 的占位符格式:
//SCSS中占位符的使用
%mt{
margin-top: 5px;
}
.block {
@extend %mt;
span {
display:block;
@extend %mt;
}
}
//编译后
.block span, .block {
margin-top: 5px;
}
.block span {
display: block;
}
总结:编译出来的 CSS 代码和使用继承基本上是相同,只是不会在代码中生成占位符 mt 的选择器。那么占位符和继承的主要区别的,占位符是独立定义,不调用的时候是不会在 CSS 中产生任何代码
;继承是首先有一个基类存在,不管调用与不调用,基类的样式都将会出现在编译出来的 CSS 代码中。
@if
指令可以根据条件来处理样式块,如果条件为 true 返回一个样式块,反之 false 返回另一个样式块。
示例:定义一个混合宏,来控制一个元素隐藏或显示,通过 @if…@else… 来判断传进参数的值来控制 display 的值
@mixin blockOrHidden($boolean:true) {
@if $boolean {
@debug "$boolean is #{$boolean}";//debug输出信息
display: block;
}
@else {
@debug "$boolean is #{$boolean}";
display: none;
}
}
.block {
@include blockOrHidden;
}
.hidden{
@include blockOrHidden(false);
}
在 Sass 的 @for 循环中有两种方式:
@for $i from start through end
@for $i from start to end
区别: through 表示包括 end 这个数,而 to 则不包括 end 这个数
示例:@for应用在网格系统生成各个格子 class 的代码:
//SCSS
$grid-prefix: span !default;
$grid-width: 60px !default;
$grid-gutter: 20px !default;
%grid {
float: left;
margin-left: $grid-gutter / 2;
margin-right: $grid-gutter / 2;
}
@for $i from 1 through 12 {
.#{$grid-prefix}#{$i}{
width: $grid-width * $i + $grid-gutter * ($i - 1);
@extend %grid;
}
}
字符串函数举例:
.test {
text: to-upper-case(aaaaa);
text: to-lower-case(aA-aAAA-aaa);
}
//编译后
.test {
text: AAAAA;
text: aa-aaaa-aaa;
}
数字函数举例:
生成随机色
random():返回 0-1 区间内的小数,
random(number):返回 1 至 number 之间的整数,包括 1 和 limit。
round(number): 返回最接近该数的一个整数,四舍五入。
max(5, 7, 9, 0, -3, -7): 返回最大值。
min(5, 7, 9, 0, -3, -7):返回最小值。
颜色函数举例:
rgba( r e d , red, red,green, b l u e , blue, blue,alpha): 函数主要用来将一个颜色根据透明度转换成 rgba 颜色。
mix( c o l o r − 1 , color-1, color−1,color-2,$weight):将两种颜色根据一定的比例混合在一起,生成另一种颜色。
sass在线转换
七色卡
调试窗口-source-scss-可查看
场景1:某些场景下会有大量冗余css代码。
使用scss的混入,定义变量,插值
语法后:
html
<div class="light-box">
<div class="item">div>
<div class="item">div>
<div class="item">div>
<div class="item">div>
div>
scss
//上浮气泡
.light-box {
width: 15rem;
height: 5rem;
position: absolute;
transform: translate(-3rem, -1rem);
overflow: hidden;
white-space: nowrap;
display: flex;
justify-content: space-around;
.item {
height: 4px;
width: 4px;
border-radius: 2px;
opacity: .8;
display: inline-block;
border: none;
background: linear-gradient(180deg, #68f8ff, rgba(6, 11, 31, 0.00));
transform: translateY(9rem);
animation: up-top 3s infinite linear;
}
.item:nth-child(1) {
opacity: .5;
animation: up-top random(6) + 1s infinite linear;
}
.item:nth-child(2) {
opacity: .4;
animation-delay: 100ms;
animation: up-top random(6) + 1s infinite linear;
}
.item:nth-child(3) {
opacity: .8;
animation-delay: 250ms;
animation: up-top random(6) + 1s infinite linear;
}
.item:nth-child(4) {
opacity: .8;
animation-delay: 600ms;
animation: up-top random(6) + 1s infinite linear;
}
@keyframes up-top {
0% {
opacity: 1;
transform: translateY(9rem);
}
100% {
opacity: .5;
transform: translateY(-6rem);
}
}
}