CSS预处理器(less与sass)

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文件,提高页面加载速度:
      • 非全局安装(安装到项目下):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嵌套:less嵌套
  • sass嵌套:sass嵌套sass语法和less类似。除了换行,其他和less编译的css没有区别

变量和计算

  • less中变量语法:@变量名:变量值(带单位);
  • sass中变量语法:$变量名:变量值(带单位);
  • 语法不同的原因:
    • less是尽量接近CSS语法
    • sass是觉得自己和CSS既然不兼容,就要避免产生混淆,因为@在CSS中是有意义的
  • less的例子less变量和计算
  • sasssass变量和计算语法不同,例子和结果除了空行上的区别,其他是没有区别的(background的函数也是相同的)

函数

原生函数

  • 内置的函数可用于处理颜色、字符串、列表、数学运算等
  1. 颜色处理函数
    颜色操作是 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-infade-out

  1. 数学函数
    数学函数在 LessSCSS 中都有,但是它们的使用方式几乎相同。
功能 Less SCSS
绝对值 (abs) abs(@number) abs($number)
四舍五入 round(@number) round($number)
向上取整 ceil(@number) ceil($number)
向下取整 floor(@number) floor($number)
百分比转换 percentage(@number) percentage($number)
  1. 字符串函数

字符串函数在 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)
  1. 列表函数

在处理列表时,SCSS 提供了更多的内置函数来操作列表,而 Less 的支持相对较弱。

功能 Less SCSS
列表长度 (length) length(@list) length($list)
获取列表中的某个元素 (nth) nth(@list, 2) nth($list, 2)
合并列表 (append) 不支持 append($list, $val)
  1. 类型检查

SCSS 中,类型检查函数很常用,而 Less 中则不常见。

功能 Less SCSS
是否为数字 (isnumber) 不支持 type-of($value) == 'number'
是否为颜色 (iscolor) 不支持 type-of($value) == 'color'
是否为字符串 (isstring) 不支持 type-of($value) == 'string'
  1. 透明度和颜色通道

SCSS 提供了更多控制颜色通道的函数,例如 red(), green(), blue(), opacity() 等,而 Less 对这类细粒度操作的支持较少。

  • 总结:

    • 基本功能:对于常见的颜色处理和数学运算,Less 和 SCSS 提供的函数是非常相似的,例如 lightendarkenabsround 等函数。

    • 高级功能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 不会被编译到CSS文件中
      • mixin 可以不加括号,但是不加括号的mixin 会被编译到CSS文件中
    • 例子: less使用mixin
  • sass:
    • 语法:
      • 定义mixin:@mixin 名称(可传参){CSS规则}
      • 调用mixin:@include 名称(可传参)
    • 注意:
      • 定义时不是选择器名称!是自定义的mixin名称
    • 例子: sass使用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规则}
    • 例子:less使用extend
  • sass:
    • 语法:当前选择器{CSS规则;@extend mixin的选择器名;当前选择器匹配的CSS规则}
    • 例子:sass使用extend

loop 循环

  • less:
  • sass:
    • sass的循环实现更加简单,因为sass支持for循环但也可以像less那样实现,只是要注意less是外部使用when,而sass是内部使用if
    • 例子:
      • sass支持的for来实现循环sass支持的for来实现循环生成的css文件和less例子生成的一样(只是多了空格)
      • 【不推荐】像less的实现方式:sass 循环例子

import CSS模块化

  • 在CSS中是可以使用import语句的,但是引入的css样式表并不会进行合并,加载的时候也不会复用,他只会在加载的时候去链接一个个的css样式表,即发出的http请求数并不会因为import而减少。而预处理器的import会在编译时将css样式表编译到一起,最后产生的是一整个css样式表,可减少发出的http请求数,提高加载性能。
  • 预处理器中的变量可以跨文件使用, 有了import以后css文件就可以按照结构划分,而不用为了性能而将所有css写到一个文件中,这样有利于维护
  • 语法:@import "相对路径的less或者sass文件名"(可忽略文件名后缀)
  • less:
    • less中使用import在实际项目中module1和module2不会那么一致,这里只是演示less中使用import的编译结果
    • 在实际项目中就可以把不同的区域样式独立在不同less文件中再最后import在一起编译出一个整体:实际演示
  • sass:
    sass的import语法和less是一样的,唯独需要注意sass的变量定义方法和less不同:sass中使用import编译结果和使用less是一样的

预处理器stylus

  • stylus有自定义函数功能(less和sass没有)
  • vscode没有插件实现自动编译,但可参考这篇文章

预处理器框架

  • 使用预处理器框架可按需使用别人的css代码
  • 目前流行的预处理器框架:
  • 作用:
    • 提供现成的mixin
    • 类似JS类库,封装常用功能

EST

  • EST是由百度工程师写的
  • 基本特性
    • variables是规定好的全局变量,比如使用@support-html5来添加支持 HTML5 新元素相关的代码(默认不支持,需要额外添加的css代码)
    • normalize用来归一化不同浏览器下的页面样式,相当于之前讲过的CSS Reset重置样式,使用EST时只需.global-normalize();就相当于一大段CSS代码了
    • reset功能同上,也是相当于之前讲过的CSS Reset重置样式
    • compatibility提供基础的兼容性封装
    • grid帮助生成自定义的栅格布局(网格布局),实际编译后是采用浮动来实现的。
      • .make-row()让元素变为(栅格外部容器)
      • .make-column()让元素变为(栅格单列容器)
      • 例子:
        • less文件grid例子less文件
        • html文件:引用编译后的less文件grid例子html文件
        • 效果:grid例子效果
    • shapes绘制基本形状的功能(比如:三角形),例子在上面grid例子最底部

面试题

常见的CSS预处理器

  • Less:原生使用Node.js编写
  • Sass:原生使Ruby编写,官方有提供Node版本,但该版本是由c++编写,安装可能比较麻烦

预处理器的作用

  • 帮助更好地组织CSS代码
  • 提高代码复用率
  • 提升可维护性

预处理器的能力

  • 嵌套:反映层级,约束选择器范围
  • 变量和计算:减少重复代码,方便维护
  • Extend和Mixin:复用代码片段(公共样式的class/清除浮动,将以前在html中的工作放到预处理器中完成)
  • 循环:适用于复杂有规律的样式(比如表格、动画)
  • import:CSS文件模块化(可以按照模块的方式组织css文件,不再受限于http加载的问题)

预处理器的优缺点

  • 优点:提高代码复用率和可维护性
  • 缺点
    • (开发/发布都)需要引入编译过程
    • 有学习成本(虽然看起来像css语法,但是less和sass都有自己独立的语法)

推荐使用预处理器吗

不一定,随着前端工程化的发展,对于css方面的提升有了更多的手段,预处理器不再是唯一的手段,所以还可能有别的方式来处理css所面临的问题。

,