CSS预处理器
- CSS预处理器是基于CSS的另一种语言
- 通过工具编译成CSS
- 添加了很多CSS不具备的特性
- 能提升CSS文件的组织方式
- 作用:
- 嵌套:反映层级,约束选择器范围
- 变量和计算:减少重复代码,方便维护
- Extend和Mixin:复用代码片段(公共样式的class/清除浮动,将以前在html中的工作放到预处理器中完成)
- 循环:适用于复杂有规律的样式(比如表格、动画)
- import:CSS文件模块化(可以按照模块的方式组织css文件,不再受限于http加载的问题)
less与sass 对比
安装
- less: less是基于node的
- 非全局安装(安装到项目下):
npm i less
则调用时使用./node_module/.bin/lessc 其他参数
- 其他参数:
xxx.less>yyy.css
即将less文件编译后放入css文件
- 其他参数:
- 全局安装:
npm i less -g
则调用时使用lessc 其他参数
- 非全局安装(安装到项目下):
- sass:
- 非全局安装(安装到项目下):
npm i node-sass
则调用时使用./node_module/.bin/node-sass 其他参数
- 其他参数:
xxx.scss>yyy.css
即将sass文件(后缀为scss)编译后放入css文件
- 其他参数:
- 全局安装:
npm i node-sass -g
则调用时使用node-sass 其他参数
- 非全局安装(安装到项目下):
编译
- 写好的less/sass文件需要编译为css文件才能使用
- less:
- vscode自动编译less
- 开发环境下避免每次修改都要手动重新编译(但在页面上解析代码,效率太低,受机器,网络影响较大):
- 引入less代码
<link rel="stylesheet/less" href="example.less" />
- 然后引入解析代码:
<script src="lesscss-1.4.0.min.js"></script>
- 引入less代码
- 其他环境预编译less文件,提高页面加载速度:
- 非全局安装(安装到项目下):
npm i less
则调用时使用./node_module/.bin/lessc xxx.less>yyy.css
xxx.less>yyy.css
即将less文件编译后放入css文件
- 非全局安装(安装到项目下):
- 全局安装:
npm i less -g
则调用时使用lessc xxx.less>yyy.css
- sass:
- vscode插件easy sass实现自动编译
- 非全局安装(安装到项目下):
npm i node-sass
则调用时使用./node_module/.bin/node-sass xxx.scss>yyy.css
xxx.scss>yyy.css
即将sass文件(后缀为scss)编译后放入css文件
- 全局安装:
npm i node-sass -g
则调用时使用node-sass xxx.scss>yyy.css
嵌套
- less嵌套:
- sass嵌套:sass语法和less类似。除了换行,其他和less编译的css没有区别
变量和计算
- less中变量语法:
@变量名:变量值(带单位);
- sass中变量语法:
$变量名:变量值(带单位);
- 语法不同的原因:
- less是尽量接近CSS语法
- sass是觉得自己和CSS既然不兼容,就要避免产生混淆,因为
@
在CSS中是有意义的
- less的例子:
- sass:语法不同,例子和结果除了空行上的区别,其他是没有区别的(background的函数也是相同的)
函数
原生函数
- 内置的函数可用于处理颜色、字符串、列表、数学运算等
- 颜色处理函数
颜色操作是 Less 和 SCSS 中最常用的功能之一,两者的基本函数较为相似。
功能 | Less | SCSS |
---|---|---|
变浅 (lighten) | lighten(@color, 10%) |
lighten($color, 10%) |
变深 (darken) | darken(@color, 10%) |
darken($color, 10%) |
增加饱和度 (saturate) | saturate(@color, 10%) |
saturate($color, 10%) |
降低饱和度 (desaturate) | desaturate(@color, 10%) |
desaturate($color, 10%) |
增加透明度,使元素更透明 | fadeout(@color, @amount) |
transparentize($color, $amount) 或 fade-out($color, $amount) |
减少透明度 (fade)使元素更不透明 | fade(@color, 50%) |
rgba($color, 0.5) 或 fade-in($color, 50%) |
设定透明度 (fade-in) | 不支持,使用 fade(@color) |
fade-in($color, 50%) |
提取透明度 (alpha) | fade(@color) |
alpha($color) |
注意:Less 的 fade
函数用于设置透明度,而 SCSS 使用 rgba
来处理透明度,同时也提供 fade-in
和 fade-out
。
- 数学函数
数学函数在 Less 和 SCSS 中都有,但是它们的使用方式几乎相同。
功能 | Less | SCSS |
---|---|---|
绝对值 (abs) | abs(@number) |
abs($number) |
四舍五入 | round(@number) |
round($number) |
向上取整 | ceil(@number) |
ceil($number) |
向下取整 | floor(@number) |
floor($number) |
百分比转换 | percentage(@number) |
percentage($number) |
- 字符串函数
字符串函数在 SCSS 中更为丰富,Less 则较少使用字符串操作函数。
功能 | Less | SCSS |
---|---|---|
转换为小写 (to-lower-case) | 不支持 | to-lower-case($string) |
转换为大写 (to-upper-case) | 不支持 | to-upper-case($string) |
字符串插入 (str-insert) | 不支持 | str-insert($string, $insert, $index) |
字符串长度 (str-length) | 不支持 | str-length($string) |
- 列表函数
在处理列表时,SCSS 提供了更多的内置函数来操作列表,而 Less 的支持相对较弱。
功能 | Less | SCSS |
---|---|---|
列表长度 (length) | length(@list) |
length($list) |
获取列表中的某个元素 (nth) | nth(@list, 2) |
nth($list, 2) |
合并列表 (append) | 不支持 | append($list, $val) |
- 类型检查
在 SCSS 中,类型检查函数很常用,而 Less 中则不常见。
功能 | Less | SCSS |
---|---|---|
是否为数字 (isnumber) | 不支持 | type-of($value) == 'number' |
是否为颜色 (iscolor) | 不支持 | type-of($value) == 'color' |
是否为字符串 (isstring) | 不支持 | type-of($value) == 'string' |
- 透明度和颜色通道
SCSS 提供了更多控制颜色通道的函数,例如 red()
, green()
, blue()
, opacity()
等,而 Less 对这类细粒度操作的支持较少。
总结:
基本功能:对于常见的颜色处理和数学运算,Less 和 SCSS 提供的函数是非常相似的,例如
lighten
、darken
、abs
、round
等函数。高级功能:SCSS 提供更多高级功能,如字符串操作、列表操作和类型检查函数。如果你需要处理这些场景,SCSS 提供的原生函数更为强大。
Less 更简单直观,而 SCSS 功能更丰富,适合复杂的样式逻辑和需要更多自定义处理的项目。
可以根据项目的复杂度选择适合的预处理器,同时也可以通过自定义函数扩展其功能。
自定义函数
- SCSS 原生支持自定义函数,而 Less 则通过 JavaScript 插件机制实现自定义函数。
- SCSS 自定义函数示例:
1
2
3
4
5
6
7
8
9@function calculate-margin($padding, $border) {
@return $padding + $border;
}
$padding: 10px;
$border: 2px;
.container {
margin: calculate-margin($padding, $border); // 输出 12px
} - Less 自定义函数示例 (通过 JavaScript 插件):
1
2
3
4
5@base-color: #3498db;
.custom-size {
// 使用 JavaScript 自定义的 double 函数
font-size: double(10px); // 输出 20px
}
mixin 复用CSS代码
- mixin:实现一大段CSS代码的复用(以前只能在HTML中实现),相当于将一段CSS代码复制到调用mixin的地方。
- less:
- 语法:
- 定义mixin:
选择器(可传参){CSS规则}
和普通class的语法基本没区别 - 调用mixin:
选择器(可传参)
和普通调用class一样
- 定义mixin:
- 注意:
- 有括号的mixin 不会被编译到CSS文件中
- mixin 可以不加括号,但是不加括号的mixin 会被编译到CSS文件中
- 例子:
- 语法:
- sass:
- 语法:
- 定义mixin:
@mixin 名称(可传参){CSS规则}
- 调用mixin:
@include 名称(可传参)
- 定义mixin:
- 注意:
- 定义时不是选择器名称!是自定义的mixin名称
- 例子:
- 语法:
extend 复用CSS代码
- 当我们频繁使用mixin时,就会导致编译产生的CSS文件中出现大量选择器中有一部分都是相同的代码。此时若是手写的CSS,我们会将同样的代码提出来写在公共class中,以此减小CSS文件体积。extend也可以做到这样的效果
- 作用:
- 将mixin代码提取出来作为公共样式(如果直接使用mixin则是疯狂复制),比起直接使用mixin 产生的css代码量会更少,但是十分复杂的情况下直接使用mixin会更好。
- 使用extend增加了代码的可维护性。
- less:
- 语法:
- 方法1:
当前选择器:extend(mixin的选择器名){当前选择器匹配的CSS规则}
- 方法2:
当前选择器{CSS规则;&:extend(mixin的选择器名);其他CSS规则}
- 方法1:
- 例子:
- 语法:
- sass:
- 语法:
当前选择器{CSS规则;@extend mixin的选择器名;当前选择器匹配的CSS规则}
- 例子:
- 语法:
loop 循环
- less:
- less中没有循环,但是mixin可以自己调用自己,所以可以通过mixin递归实现循环的效果。
- 例子:](https://i0.wp.com/ww1.sinaimg.cn/large/005H7IVsgy1ggswfwbuxwj30q70hmtj2.jpg)
- sass:
- sass的循环实现更加简单,因为sass支持for循环。但也可以像less那样实现,只是要注意less是外部使用when,而sass是内部使用if
- 例子:
- sass支持的for来实现循环:生成的css文件和less例子生成的一样(只是多了空格)
- 【不推荐】像less的实现方式:
import CSS模块化
- 在CSS中是可以使用import语句的,但是引入的css样式表并不会进行合并,加载的时候也不会复用,他只会在加载的时候去链接一个个的css样式表,即发出的http请求数并不会因为import而减少。而预处理器的import会在编译时将css样式表编译到一起,最后产生的是一整个css样式表,可减少发出的http请求数,提高加载性能。
- 预处理器中的变量可以跨文件使用, 有了import以后css文件就可以按照结构划分,而不用为了性能而将所有css写到一个文件中,这样有利于维护。
- 语法:
@import "相对路径的less或者sass文件名"
(可忽略文件名后缀) - less:
- 在实际项目中module1和module2不会那么一致,这里只是演示
- 在实际项目中就可以把不同的区域样式独立在不同less文件中再最后import在一起编译出一个整体:
- sass:
sass的import语法和less是一样的,唯独需要注意sass的变量定义方法和less不同:编译结果和使用less是一样的
预处理器stylus
- stylus有自定义函数功能(less和sass没有)
- vscode没有插件实现自动编译,但可参考这篇文章
预处理器框架
EST
- EST是由百度工程师写的
- 基本特性:
- variables是规定好的全局变量,比如使用
@support-html5
来添加支持 HTML5 新元素相关的代码(默认不支持,需要额外添加的css代码) - normalize用来归一化不同浏览器下的页面样式,相当于之前讲过的CSS Reset重置样式,使用EST时只需
.global-normalize();
就相当于一大段CSS代码了 - reset功能同上,也是相当于之前讲过的CSS Reset重置样式
- compatibility提供基础的兼容性封装。
- grid帮助生成自定义的栅格布局(网格布局),实际编译后是采用浮动来实现的。
.make-row()
让元素变为行(栅格外部容器).make-column()
让元素变为列(栅格单列容器)- 例子:
- less文件:
- html文件:引用编译后的less文件
- 效果:
- shapes绘制基本形状的功能(比如:三角形),例子在上面grid例子最底部
- variables是规定好的全局变量,比如使用
面试题
常见的CSS预处理器
- Less:原生使用Node.js编写
- Sass:原生使Ruby编写,官方有提供Node版本,但该版本是由c++编写,安装可能比较麻烦
预处理器的作用
- 帮助更好地组织CSS代码
- 提高代码复用率
- 提升可维护性
预处理器的能力
- 嵌套:反映层级,约束选择器范围
- 变量和计算:减少重复代码,方便维护
- Extend和Mixin:复用代码片段(公共样式的class/清除浮动,将以前在html中的工作放到预处理器中完成)
- 循环:适用于复杂有规律的样式(比如表格、动画)
- import:CSS文件模块化(可以按照模块的方式组织css文件,不再受限于http加载的问题)
预处理器的优缺点
- 优点:提高代码复用率和可维护性
- 缺点:
- (开发/发布都)需要引入编译过程
- 有学习成本(虽然看起来像css语法,但是less和sass都有自己独立的语法)
推荐使用预处理器吗
不一定,随着前端工程化的发展,对于css方面的提升有了更多的手段,预处理器不再是唯一的手段,所以还可能有别的方式来处理css所面临的问题。