css预处理
一、什么是css预处理
css预处理器是一种新的编程语言,为css增加一些编程的特性,无需考虑兼容性问题。CSS
预编译的工作原理是提供便捷的语法和特性供开发者编写源代码,随后经过专门的编译工具将源码转化为CSS
语法。前端工程化的里程碑。
二、为什么需要css预处理
一样东西的出现肯定是为了解决某种东西的缺陷。css预处理也不例外,它的出现是来解决css的一些缺点的。
2.1css有什么样的缺点?
(1)语法不够强大,无法嵌套书写,开发中需要重复写很多遍选择器,造成代码冗余
(2)没有变量、样式复用的规则,难以维护,开发效率低
2.2css预处理的优点?
(1)提供样式复用的机制
(2)减少代码冗余,便于维护,开发效率高
2.3css预处理的特点?
(1)基于css的另一种编程语言
(2)通过中间工具编译成css
(3)增加一些css不具备的新特性
(4)提升css的文件组织
2.4css提高开发效率
(1)增强编程能力
(2)增强可复用性
(3)增强可维护性
(4)浏览器更好的兼容性
三、css预处理能力
(1)嵌套—层级和约束
(2)变量和计算—减少重复冗余代码
(3)Mixin/Extend复用代码片段
(4)模块化—importCSS文件
(5)循环 适应于复杂有规律的样式
四、css三大主流预处理器:Sass、Less、stylus
三个框架简介
1、Sass
:2007年诞生,最早也是最成熟的CSS预处理器,拥有ruby社区的支持和compass这一最强大的css框架,目前受LESS
影响,已经进化到了全面兼容CSS的SCSS
。
现在的Sass
已经有了两套语法规则:
- 一个依旧是用缩进作为分隔符来区分代码块的
- 另一套规则和CSS一样采用了大括号({})作为分隔符。这一种语法规则又名
SCSS
,在Sass3之后的版本都支持这种语法规则。
2、Less
:2009年出现,受Sass
的影响较大,但又使用CSS
的语法,让大部分开发者和设计师更容易上手,在ruby社区之外支持者远超过Sass
,其缺点是比起Sass
来,可编程功能不够,不过优点是简单和兼容CSS,反过来也影响了SASS演变到了SCSS的时代,著名的Twitter Bootstrap就是采用LESS
做底层语言的。
3、Stylus
:2010年产生,来自Node.js社区,主要用来给Node项目进行CSS预处理支持,在此社区之内有一定支持者,在广泛的意义上人气还完全不如SASS和LESS。Stylus被称为是一种革命性的新语言,提供一个高效、动态、和使用表达方式来生成CSS,以供浏览器使用。Stylus同时支持缩进和CSS常规样式书写规则。
五、css预处理less
5.1less的安装
npm install -g less
lessc styles.less styles.css
5.2less的编译
(1)nodejs环境中使用less
- 命令行lessc styles.less styles.css
- 插件:watcher-lessc(编译的同时添加监控)命令watcher-lessc -i style.less -o style.css
-i:表示输入文件,即要编译的less文件
-o:表示输出文件,即编译出来的css文件
path:在-o后跟的路径是编译出来的css文件
(2)浏览器环境使用less
<link rel="stylesheet/less" type="text/css" herf="styles.less">
<script src="https://cdnjs.cloudflare.com/ajax/libs/less.js/3.11.1/less.min.js" ></script>
(3)工具编译
(4)在线工具
(5)插件—vscode 的easy less插件
5.3less的功能
(1)变量
@符号开头定义变量,结尾加分号;
/*less*/
@width: 20px;
@height: @width + 20px;
#header {
width: @width;
height: @height;
}
/*编译后的css*/
#header {
width: 20px;
height: 40px;
}
(2)混合
- 无参数方法
#或者.都可以作为方法前缀,后面加不加()都可以,建议加上(),以便于区分
/* less */
.box(){
background:#fff;
}
#content{
.box();
}
/* 编译后的css */
#content{
background:#fff;
}
- 默认参数方法
传参必须带单位,@arguments代指全部参数
/* less */
.border(@a:20px,@b:50px,@c:30px,@color:#000){
border:solid 1px @color;
box-shadow: @arguments;//指代的是 全部参数
}
#main{
.border(0px,5px,30px,pink);//必须带着单位
}
#content{
.border;//等价于 .border()
}
/* 编译后的css */
#main{
border:solid 1px pink;
box-shadow:0px,5px,30px,pink;
}
#content{
border:solid 1px #000;
box-shadow: 20px 50px 30px #000;
}
- 方法的匹配模式
①第一个参数找到方法中匹配度最高的,如果匹配度相同,将会全部选择,存在样式覆盖
②如果匹配的参数是变量,则会匹配(@__)
/* Less */
.triangle(top,@width:20px,@color:#000){
border-color:transparent transparent @color transparent ;
}
.triangle(right,@width:20px,@color:#000){
border-color:transparent @color transparent transparent ;
}
.triangle(bottom,@width:20px,@color:#000){
border-color:@color transparent transparent transparent ;
}
.triangle(left,@width:20px,@color:#000){
border-color:transparent transparent transparent @color;
}
.triangle(@_,@width:20px,@color:#000){
border-style: solid;
border-width: @width;
}
#main{
.triangle(left, 50px, #999)
}
/* 编译后的 CSS */
#main{
border-color:transparent transparent transparent #999;
border-style: solid;
border-width: 50px;
}
-
命名的规范
子方法可以使用上一层传进的方法;
必须先引进命名的空间才能使用方法;
选择器>前面的父元素不能加括号;
/* Less */ #card(){ background: #723232; .d(@w:300px){ width: @w; #a(@h:300px){ height: @h;//可以使用上一层传进来的方法 } } } #box{ #card > .d > #a(100px); // 父元素不能加 括号 } #main{ #card .d(); } #con{ //不得单独使用命名空间的方法 //.d() 如果前面没有引入命名空间 #card ,将会报错 #card; // 等价于 #card(); .d(20px); //必须先引入 #card } /* 编译后的 CSS */ #box{ height:100px; } #main{ width:300px; } #con{ width:20px; }
-
Less有when
/* Less */
#card{
// and 运算符 ,相当于 与运算 &&,必须条件全部符合才会执行
.border(@width,@color,@style) when (@width>80px) and(@color=pink){
border:@style @color @width;
}
// not 运算符,相当于 非运算 !,条件为 不符合才会执行
.background(@color) when not (@color>=#666){
background:@color;
}
// , 逗号分隔符:相当于 或运算 ||,只要有一个符合条件就会执行
.font(@size:20px) when (@size>66px) , (@size<100px){
font-size: @size;
}
}
#main{
#card>.border(200px,pink,solid);
#card .background(#111);
#card > .font(40px);
}
/* 编译后的 CSS */
#main{
border:solid pink 200px;
background:#111;
font-size:40px;
}
- 参数的数量不固定
/* Less */
.boxShadow(...){
box-shadow: @arguments;
}
.textShadow(@a,...){
text-shadow: @arguments;
}
#main{
.boxShadow(1px,6px,88px,pink);
.textShadow(1px,6px,88px,pink);
}
/* 编译后的 CSS */
#main{
box-shadow: 1px 6px 88px pink;
text-shadow: 1px 6px 88px pink;
}
- !import用法
/* Less */
.border{
border: solid 1px pink;
padding: 50px;
}
#main{
.border() !important;
}
/* 生成后的 CSS */
#main {
border: solid 1px pink !important;
padding: 50px !important;
}
- 属性拼接(+_表示空格,+表示逗号)
//逗号
/* Less */
.boxShadow() {
box-shadow+: inset 0 0 10px #666;
}
.main {
.boxShadow();
box-shadow+: 0 0 20px pink;
}
/* 编译后的 CSS */
.main {
box-shadow: inset 0 0 10px #666, 0 0 20px pink;
}
//空格
/* Less */
.Animation() {
transform+_: scale(1);
}
.main {
.Animation();
transform+_: rotate(16deg);
}
/* 编译后的CSS */
.main {
transform: scale(1) rotate(16deg);
}
(3)嵌套
允许把具有层级关系的类名/选择器进行嵌套使用,注意需要用花括号进行包裹
- 嵌套使用
/* Less */
.boxcontent {
margin: 0 auto;
.box {
display: flex;
.item {
color: pink;
}
}
}
/* 编译后的CSS */
.boxcontent{
margin: 0 auto;
}
.boxcontent .box{
display: flex;
}
.boxcontent .box .item{
color: pink
}
- 使用符号&替代父元素
/* Less */
#header{
&:after{
content:"hello!";
}
.title{
font-weight:bold;
}
&_content{// & 替代 #header
margin:0px auto;
}
}
/* 编译后的 CSS */
#header::after{
content:"hello!";
}
#header .title{ //嵌套
font-weight:bold;
}
#header_content{//没有嵌套
margin:0px auto;
}
- @media媒体查询和冒泡规则
不是每一个类名都会单独编译出一个@media,多个相同条件的媒体查询不会进行合并。
/* Less */
.component {
width: 300px;
@media (min-width: 768px) {
width: 600px;
@media (min-resolution: 192dpi) {
background-color: pink;
}
}
@media (min-width: 1280px) {
width: 800px;
}
}
/* 编译后的 CSS */
.component {
width: 300px;
}
@media (min-width: 768px) {
.component {
width: 600px;
}
}
@media (min-width: 768px) and (min-resolution: 192dpi) {
.component {
background-color: pink;
}
}
@media (min-width: 1280px) {
.component {
width: 800px;
}
}
(4)运算
算术运算符 +
、-
、*
、/
可以对任何数字、颜色或变量进行运算
/*less*/
@width: 20px;
@height: @width + 20px;
#header {
width: @width;
height: @height;
}
/*编译后的css*/
#header {
width: 20px;
height: 40px;
}
(5)函数
- 逻辑函数
①if根据实际情况返回结果
②boolean存储布尔值,用if判断
- 字符串函数
①escape可以将url编码应用输入字符串的特殊字符串
②replace替代字符串中的文本
- 数学函数
①ceil 向上舍入到下一个最高整数
②floor 向下舍入到下一个最小整数
③percentage 将浮点数转换为百分比字符串
④sqrt 计算一个数的平方根。保持单位不变
⑤abs 计算一个数的绝对值。保持单位不变
⑥min 返回一个或多个值中的最小值
⑦max 返回一个或多个值中的最大值
- 其他函数
①isnumber 判断给定的值 是否 是一个数字
②iscolor 判断给定的值 是否 是一个颜色
③isurl 判断给定的值 是否 是一个url
④saturate增加一定数值的颜色饱和度
⑤lighten增加一定数值的颜色亮度
⑥darken降低一定数值的颜色亮度
⑦fade给颜色设定一定数值的透明度
⑧mix根据比例混合两种颜色
(6)导入
在一个 less
文件中引入其他的 less
文件,一般在一个 less
文件的最顶部进行引入
//写法一
@import url(a.less);
//写法二
@import 'a.less';
//写法三 也可引入css
@import 'style.css'
(7)扩展
继承匹配声明中的全部样式
/* Less */
.animation{
transition: all .3s ease-out;
.hide{
transform:scale(0);
}
}
#main{
&:extend(.animation);
}
#con{
&:extend(.animation .hide);
}
/* 编译后的 CSS */
.animation,#main{
transition: all .3s ease-out;
}
.animation .hide , #con{
transform:scale(0);
}
(8)注释
/* Less */
// 普通注释,不会被编译到 CSS 中
/*
多行注释,会被编译到 CSS 中
*/
/* 编译后的 CSS */
/*
多行注释,会被编译到 CSS 中
*/
六、css预处理sass
6.1sass的安装
npm install -g sass
6.2sass的编译
(1)插件—vscode 的Live Sass Compiler插件
(2)命令行编译
- 单文件编译 一个scss文件—一个css文件
// sass input.scss:output.css
// sass input.scss output.css
attention:冒号和空格的使用
一对一(一个scss—一个css)用空格
多对多(一个文件夹—一个文件夹)用冒号
(3)编译配置
sass -h //查看详细配置
sass --help//查看详细配置
--style//调试map,debug
--sourcemap//调试map,debug
(4)–watch 监听文件变化
--watch //监听单个css文件
sass --watch // 监听单个文件夹
sass --watch A:B//监听多个文件夹
(5)–style
css有两种格式
-
expanded:标准的没有经过压缩的格式,全部字符展开标准css
-
compressed:去除空白字符,全部css压缩为一行
旧版的Ruby还有两种nested、compact
sass input.scss:output.scss --style=expanded//可以指定编译格式
(6)–no–source–map 调试
相当于一个中间工具,在处理前的代码和处理后的代码之间搭建桥梁,可以通过它定位源代码,js可以断点调试
sass input.scss output.css --source-map //source map默认开启 生成后缀名 .css.map文件
sass input.scss output.css --no-source-map //取消调试map
(7)–source-map-urls 链接到Sass
控制source maps如何将 Sass 生成的 css 链接回 Sass 文件
支持两种链接
- relative 默认
- absolute 绝对路径链接
链接生成的是.css.map文件中的sources键对应的值
sass --source--map--urls=relative styletest.scss styletest.css //生成../sass/styletest.scss
sass --source-map-urls=absolute styletest.scss styletest.css //生成 file:///D:/sass/styletest.scss
6.3sass的功能
(1)变量
$符号开头定义变量,结尾加分号;
/* sass */
$wang:rgb(166,166,166);
h1{
color:$wang;
}
/* 编译后的css */
h1{
color:rgb(166,166,166);
}
(2)嵌套
/* sass */
.boxcontent {
margin: 0 auto;
.box {
display: flex;
.item {
color: pink;
}
}
}
/* 编译后的css */
.boxcontent{
margin: 0 auto;
}
.boxcontent .box{
display: flex;
}
.boxcontent .box .item{
color: pink
}
(3)混合
- 无参数方法
/* sass */
@mixin minxin {
color: pink;
a {
font-size: 30px;
}
}
div{
@include minxinx; /*@include名字调用*/
}
/* 编译后的css */
div {
color: pink;
}
div a {
font-size: 12px;
}
- 带参数方法,参数名前面要写$
/* sass */
@mixin mixin($one,$two) {
color: $one;
a {
color: $one;
font-size: $two;
}
}
div{
@include mixin(pink,6px);
}
/* 编译后的css */
div {
color: pink;
}
div a {
color: pink;
font-size: 6px;
}
(5)扩展
关键字@extend,继承.aaa和.aaa相关的都继承了
/* sass */
.aaa{
color: pink;
}
.aaa b{
font-size: 6px;
}
.bbb{
@extend .aaa;
background-color: #000;
}
/* 编译后的css */
.aaa, .bbb {
color: pink;
}
.aaa b, .bbb b {
font-size: 6px;
}
.bbb {
background-color: #000;
}
(6)导入
@import: "scssstylesheet.scss";
(7)计算
/* sass */
$wang: 20px;
div{
margin: (10px*2);
left: 20px + $chang;
}
/* 编译后的css */
div {
margin: 20px;
left: 40px;
}
(8)函数
自定义函数
@function 名字(参数1,参数2,..){
....
}
/* sass */
@function fun ($f)
{
@return $f+10px;
}
div{
width: fun(5px);
}
/* 编译后的css */
div {
width: 15px;
}
sass也提供一些内置的函数,以便于生成多种颜色
①hsl (色相,饱和度,明度)
body{
background-color: hsl(5,66%,66%);
}
②hsl (色相,饱和度,明度,不饱和度)
body{
background-color: hsl(5,66%,66%,0,5);
}
③adjust-hue(颜色,调整的度数)
body{
background-color: adjust-hue(hsl(66,100,66%), 66deg);
}
④lighten 调亮
body{
background-color: lighten(rgb(166, 166, 166),66%);
}
⑤darken 调暗
body{
background-color: darken(rgb(166, 166, 166),66%);
}
⑥saturate (颜色,百分比)颜色调纯
body{
background-color: saturate(pink,66%);
}
⑦desaturate (颜色,百分比)颜色不纯
body{
background-color: desaturate(pink,66%);
}
(9) Interpolation #{变量}
/* sass */
$boxcolor: color;
body{
#{$boxcolor}:pink;
}
/* 编译后的css */
body{
color:pink;
}
(10)if判断
@if 判断条件 {
.......执行语句...
} @else {
...else可写可不写....
}
/* sass */
$wang: false;
body{
@if false{
color: pink;
}
@if 2>3 {
background-color: white;
}@else{
background-color: blue;
}
}
/* 编译后的css */
body {
background-color: blue;
}
(11)循环
- for循环
结束值不执行:
@for 变量 from 开始值 through 结束值 {
......
}
结束值也执行:
@for 变量 from 开始值 to 结束值 {
......
}
/* sass */
@for $i from 1 to 3 {
.div#{$i}{
width: $i*10px;
height: $i*20px;
}
}
/* 编译后的css */
.div1 {
width: 10px;
height: 20px;
}
.div2 {
width: 20px;
height: 40px;
}
- 列表循环
@each 变量 in 列表{
...
}
/* sass */
$color: red green blue;
@each $i in $color {
.div#{$i}{
color: $i;
}
}
/* 编译后的css */
.divred {
color: red;
}
.divgreen {
color: green;
}
.divblue {
color: blue;
}
- while循环
@while 条件 {
...
}
/* sass */
$hightt: 1;
@while $hightt<4 {
.div#{$hightt}{
height: $hightt*10px;
}
$hightt : hightt+1;
}
/* 编译后的css */
.div1 {
height: 10px;
}
.div2 {
height: 20px;
}
.div3 {
height: 30px;
}
七、三个主流预处理的优缺点
7.1、Less
优点
①可以在浏览器运行,订制主题功能
缺点
①编程功能弱,不支持判断循环
②mixin/extend语法复杂,容易混淆
7.2、Sass
优点
①用户广泛,学习资源多
②sass的编程功能强大,支持判断循环
③Bootstrap等使用scss
④丰富的库,如Compass/Bourbon
缺点
①安装经常出错,node -sass经常报错,需要cnpm换源或者手工安装
7.3、stylus
优点
①源于node社区,与js关系密切,有专门的js API
②支持Ruby框架
③强大的支持和功能
缺点
①资源较少,学习人比较少
八、Less和Sass的区别
(1)Less环境比Sass简单
Sass的环境安装需要安装Ruby环境,Less基于js引入Less.js处理代码输出css到浏览器/编译成css文件
(2)Less使用比Sass简单
Less没有剪裁css原有特性,在css语法基础上,容易上手
(3)Sass功能比Less强大
①sass有变量和作用域
php:KaTeX parse error: Expected ‘EOF’, got ‘#’ at position 15: variable、Ruby:#̲{variable}、有全局变量局部变量和优先级
②sass有函数概念
sass有@function、@return,类似js的封装逻辑
sass有@mixin,不是function的编程逻辑,但可以提高css代码片段的复用性和模块化
ruby提供丰富的内置api
③进程控制,if判断和循环
(4)Less和Sass处理机制不一样
Less通过客户端处理,Sass通过服务端处理,Sass解析效率比Less慢
(5)变量的定义不同Less用@,Sass用$
九、总结
css预处理是前端工程化的一部分,有利于css代码的维护。开发中建议用sass,它有一些成熟的框架Compass,Sass的热度比Less高一点。Sass是一个强大的处理器。bootstrap(Web框架)最新推出的版本4,使用的就是Sass。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/16153.html