「多图预警」这一次,带你彻底掌握Less!

2,483 阅读26分钟

前言

我们都知道CSS的编写有些令人沮丧,尤其是涉及到具有数千行代码的更严肃的项目时。你最终将在各地重复相同的规则,要保持CSS的可维护性,需要付出大量的努力

幸运的是,Web开发社区已经解决了这个问题。现在,我们有了CSS预处理器,例如LessSassStylus,虽然SassStylus相比于Less功能更为丰富,但是学习成本也相应的变高。

Less没有去掉任何CSS的功能,并且给CSS带来了很多特性,使得LESS能够和CSS无缝地紧密结合在一起。因此,你可以平滑地由CSS迁移到LESS,本文将从以下几个方面讨论Less的用法。

什么是LESS

Less是一个CSS预编译器,意思指的是它可以扩展CSS语言,添加功能如允许变量(variables),混合(mixins),函数(functions)和许多其他的技术,让你的CSS更具维护性,主题性,扩展性。

入门

要使用Less需要先将其编译成CSS才能被浏览器识别使用。当然有很多方式可以实现,这里我们只讲node编译的方式

在命令行 使用npm安装

npm install -g less

当Less文件写好后,就可以使用一下命令进行编译

lessc styles.less > styles.css

假设我们已经用Less编写了styles.less。在上面的代码行中,我们的代码将在styles.css中将其转换为纯CSS 。剩下的就是将此CSS文件链接到我们的HTML。

变量

Less的主要功能之一是能够像使用标准编程语言一样创建变量。它们可以存储经常使用的任何类型的值:颜色尺寸选择器字体名称URL等。使得可以尽可能的重用,因为其变量是常量 ,所以只能定义一次。

语法 🎉:@name: value; (@color: #999;)

Less以@开头定义变量,使用时直接使用@name

普通变量

直接采用变量作为属性名:

// 命名:
@color: red;
// 调用:
div {
  color: @color;
}

编译结果👇:

div {
  color: red;
}

作为选择器和属性名的变量

作为选择器需要用花括号{ }来包含。作为属性名时,和属性值的调用方法一样:

@mySelector: #wrap;
@Wrap: wrap;
@borderStyle: width;
.@{Wrap}{
  @{borderStyle}: 150px;
}
@{mySelector}{
  @{borderStyle}:  150px;
}

编译结果👇:

.wrap {
  width: 150px;
}
#wrap {
  width: 150px;
}

作为URL

同属性变量一样,URL变量引用的时候也是需要加花括号的,这样在相同路径下的图片或文件就可以声明一个URL变量,后接具体图片/文件名,路径不要忘记加引号

@myURL: '../img';
body {
  background: url('@{myURL}/logo.png');
}

编译结果👇:

body {
  background: url('../img/logo.png');
}

声明变量

有点类似于下面的混合方法,如下所示声明变量并引用时,就如同js中一个方法调用一样来使用.

  • 结构: @name: { 属性: 值 ;};
  • 使用:@name();
@Rules: {
  width: 200px;
  height: 200px;
};
div {
  @Rules();
}

编译结果👇:

div {
  width: 200px;
  height: 200px;
}

延迟加载

变量是延迟加载的,在使用前不一定要预先声明,可以简单理解为变量的提升

// 下面的变量会解析到当前作用域的前面。
div{
	font-size:@font-size;
}
@font-size:12px;  
@color:red; 

变量运算

Less 语言中支持加减乘除运算操作,这四个运算符可以对任何数字、颜色或变量进行运算。一般运算符在进行加、减计算之前会进行单位换算。计算规则如下

  • 加减法时 以第一个数据的单位为基准
  • 乘除法时 注意单位一定要统一
@content-height: 1000px;
@nav-height: 80px;
@footer-height: 2 * 40px;
@table-height: @nav-height + @content-height - @footer-height;
@width: 300px;
@color: #222;

.content-wrapper {
  width: 100%;
  height: calc(~'100vh - @{nav-height} - @{footer-height}');
}

.table-wrapper {
  width: @width - 20;
  height: @table-height;
  color: @color*2;
  background-color: @color + #111;
}

编译结果👇:

.content-wrapper {
  width: 100%;
  height: calc(100vh - 80px - 80px);
}
.table-wrapper {
  width: 280px;
  height: 1000px;
  color: #444444;
  background-color: #333333;
}

变量作用域

在定义一个变量多次时,只会使用最后定义的变量,Less会从当前作用域向上搜索,这个行为类似于CSS定义中始终使用最后定义的属性值(CSS层叠性)。

@font-size: 12px;
div {
  @font-size: 15px;
  font-size: @font-size;
  @font-size: 20px;
  // 20px会提升到15px和调用之间,所以20px会把15px层叠掉,在当前作用域中,离调用最近的20px,因此会先找到20px
}
html {
  font-size: @font-size;
  // 在div内部定义的只会在div内部起作用,所以根据就近原则html会找到离它最近的第一次定义的12px
}

编译结果👇:

div {
  font-size: 20px;
}
html {
  font-size: 12px;
}

用变量去定义变量

/* Less */
@fnord:  "I am fnord.";
@var:    "fnord";
#wrap::after{
  content: @@var; //将@var替换为其值 content:@fnord;
}
/* 生成的 CSS */
#wrap::after{
  content: "I am fnord.";
}

混合

混合就是一种将一系列属性从一个规则集引入(混合)到另一个规则集的方式。规则集可以理解为CSS样式,当我们的样式重复出现时,我们可以采用混合的方式来减少代码冗余。

普通混合

.bgc {
  background-color: pink;
}
body {
  .bgc; 
}

编译结果👇:

.bgc {
  background-color: pink;
}
body {
  background-color: pink;
}

不带输出的混合

如果你想要创建一个混合集,但是却不想让它输出到你的样式中,既单纯定义只是用于调用时,可以使用。

在不想输出的混合集的名字后面加上一个括号,就可以实现

.bgc() {
  background-color: pink;
}
body {
  .bgc(); // 这个括号也可以不写,但是为了避免代码混淆,建议写成`.bgc()`
}

编译结果👇:

body {
  background-color: pink;
}

带选择器的混合

.my_hover() {
  // 伪类前使用 & 详情见 Less的嵌套规则
  &:hover {
    color: pink;
  }
}
button {
  .my_hover();
}
/* 只是将里面的CSS代码拿过来,相当于:
button{
    &:hover{
        color: pink;
    }
}
*/

编译结果👇:

button:hover {
  color: pink;
}

带参数的混合

当属性一致但是属性值不一致时,我们可以通过传参的方式改变属性值,就可以给各个选择器重复调用

  • es6一样,Less 可以使用默认参数,如果没有传参数,那么将使用默认参数。

  • 参数可以使用逗号或分号分隔。 (建议使用分号,因为逗号具有双重含义:可以将其解释为mixin参数分隔符或者是css列表分隔符

    • 如果传参的括号里面都是以逗号或者分号分割,那么会依次传给各个参数值
    • 如果参数中既有括号又有分号,就会将分号前面的看作一个整体作为参数
  1. 都是以分号分割参数
.border(@border_color;@width:10px) {
  border: 1px solid @border_color;
  width: @width;
}
div {
  .border(pink,20px);
}
p {
  .border(red);
}

编译结果👇:

div {
  border: 1px solid pink;
  width: 20px;
}
p {
  border: 1px solid red;
  width: 10px;
}
  1. 参数中既有括号又有分号
.mini(@color;@fontFamily) {
  color: @color;
  font-family: @fontFamily;
}
.div {
  .mini(pink;Arial, Verdana, Geneva, sans-serif);
}

编译结果👇:

.div {
  color: pink;
  font-family: Arial, Verdana, Geneva, sans-serif;
}
  1. 定义多个具有相同名称和参数数量的mixins是合法的,Less会根据它的参数数量来决定是否使用:
.border(@border_color;@width:10px) {
  border: 1px solid @border_color;
  width: @width;
}
.border(@border_color) {
  height: 2px;
}
div {
  .border(pink;20px);
}
p {
  .border(red);
}

编译结果👇:

div {
  border: 1px solid pink;
  width: 20px;
}
p {
  border: 1px solid red;
  width: 10px;
  height: 2px; 
}
可以看到只带了一个参数的选择器p,同时使用了两个mixin

命名参数

引用mixin时可以通过参数名称而不是参数的位置来为mixin提供参数值,任何参数都可以通过它的名称来引用,这样就不必按照任意特定的顺序来使用参数

.div(@border_color;@margin:2) {
  border: 1px solid @border_color;
  margin: @margin;
}
div {
  .div(@margin:3;#ccc); // 这样来指定第一个参数赋值给@margin变量,就不用按照原先定义的指定顺序输入
}

编译结果👇:

div {
  border: 1px solid #ccc;
  margin: 3;
}

@arguments变量

@arguments变量表示可变参数,意思是形参从先到后的顺序。注意:这个是参数值位置必须是一一对应。

.border(@a:20px;@b:solid;@color:white) {
  border: @arguments;
}
.div {
  .border();
}

编译结果👇:

.div {
  border: 20px solid white;
}

匹配模式

传值的时候定义一个字符,在使用的时候使用哪个字符,就调用哪条规则。根据不同功能定义字符,类似一个标识符,适用于相同属性值在类似属性中的应用,例如下例都是设置边框圆角。

.border(all;@color:#000;@w:5px) {
  border-radius: @w;
}
.border(t_l;@color:#000;@w:5px) {
  border-top-left-radius: @w;
}
.border(@_;@color:#000;@w:5px) {
  border-style: solid;
  border-color: transparent transparent transparent @color;
}
// 想要四个圆角就调用 all
header {
  .border(all;pink;50%);
}
// 想要左上一个圆角就调用 t_l
header {
  .border(t_l;pink;50%);
}
// 类似的我们还可以定义右上、左下、右下等,这样就可以在适时调用合适的方法了

编译结果👇:

header {
  border-radius: 50%;
  border-style: solid;
  border-color: transparent transparent transparent pink;
}
header {
  border-top-left-radius: 50%;
  border-style: solid;
  border-color: transparent transparent transparent pink;
}
  • 第一个参数allt_l要会找到方法中匹配程度最高的,如果匹配程度相同,将全部选择,并存在着样式覆盖替换。
  • 如果匹配的参数是变量,则将会匹配,如@_

得到混合变量中变量的返回值

.average(@x;@y) {
  @average: ((@x + @y) / 2);
}
div {
  .average(10px;20px); // 调用进行计算
  padding: @average; // 得到混合变量中变量的返回值
}

编译结果👇:

div {
  padding: 15px;
}

解析 🚀:

之所以可以得到@average是因为,混合是将规则集(这里为CSS样式表)拿过来 也就会变成如下代码:

div{
      // 调用时 进行变量赋值
      @x:10px;
      @y:20px;
      // 将规则集混合
      @average: ((@x + @y) / 2);
      // 这样就是一个作用域啦~ 当然可以使用啦~
      padding:@average;
}

嵌套规则(netsted-rules)

嵌套规则它模仿了HTML的结构,让我们的CSS代码更加简洁明了清晰

子元素嵌套

可以将子元素的样式直接写在父元素的里面,形成嵌套

header {
  color: green;
  // 表示选择 header的子元素p 并设置其样式
  p {
    color: red;
  }
}

编译结果👇:

header {
  color: green;
}
header p {
  color: red;
}

父元素选择器(&在前)

&表示当前选择器的所有父选择器

#header {
  &:after {
    content: 'Less is more!';
  }
  .title {
    font-weight: bold;
  }
  &_content {
    //理解方式:直接把 & 替换成 #header
    margin: 20px;
  }
  &.disable {
    background: #ccc;
  }
}

编译结果👇:

#header:after {
  content: 'Less is more!';
}
#header .title {
  font-weight: bold;
}
#header_content {
  margin: 20px;
}
#header.disable {
  background: #ccc;
}

改变选择器的顺序(&在后)

&放在当前选择器之后,就会将当前选择器插入到所有的父选择器之前

.header {
  p {
    .conter & {
      // 注意 & 前有空格
      color: red;
    }
    .footer& {
      // 没有空格时,提到前面时也没有空格
      color: green;
    }
  }
}

编译结果👇:

.conter .header p {
  color: red;
}
.footer.header p {
  color: green;
}

组合使用生成所有可能的选择器列表(两个&)

.header,
ul,
li {
  & & {
    color: pink;
  }
}

编译结果👇:

.header .header,
.header ul,
.header li,
ul .header,
ul ul,
ul li,
li .header,
li ul,
li li {
  color: pink;
}

输出结果时选择器总个数为

解析 🚀:

第一个&表示当前父选择器,即先取.header,选中之后第二个&将其插入到所有父元素之前, 即:将其分别插入到3个父选择器之前,然后继续取ul相同做法,依次类推,就形成了这样的组合

运算(operations)

在Less中任何数值,颜色和变量都可以进行运算

数值型运算

运算时Less会为你自动推断数值的单位,所以你不必每一个值都加上单位。

运算符与值之间必须以空格分开,涉及优先级时以( )包裹进行优先级运算。

.width {
  width: (100px + 50) * 2;
}

编译结果👇:

.width {
  width: 300px;
}

颜色运算

Less 在运算时,颜色值会先转换为rgb模式,然后再转换为16进制的颜色值并返回。因为是转换为rgb模式,而rgb的取值范围在0~255之间,所以不能超过这个范围的值。在对16进制颜色进行运算时会忽略#

.content {
  color: black + 21; // black的rgb为(0,0,0)所以运算后为(21,21,21)
}
.header {
  color: #666 - #444; // 输出为 #222
}
.footer {
  color: rgb(255, 0, 0) + 15; // 运算后为(255,15,15),因为最大为255,所以第一位不变
}

编译结果👇:

.content {
  color: #151515;
}
.header {
  color: #222222;
}
.footer {
  color: #ff0f0f;
}

命名空间

有时候我们需要将一些混合组合在一起,可以通过嵌套多层id或者class来实现。这样类似于进行了一种封装可以供重复调用,格式为 大混合 > 实现的类或ID 这样的使用方式 我们称为命名空间,可以简单理解为通过名字来找到我们需要的空间

我们可以在Less混合中为自己封装一些比较日常比较常用的类名,通过命名空间来使用,来使编码更加有效率,如我们在混合里面分别定义颜色,宽度和高度等,当需要这其中的某些样式时,我们就可以通过命名空间来找到其中我们需要的具体样式。

#card() {
  background: #723232;
  .d(@w:300px) {
    width: @w;

    #a(@h:300px) {
      height: @h; //可以使用上一层传进来的方法
    }
  }
  .c {
    color: #fff;
  }
}
// 对命名空间进行调用
#wrap {
  #card > .d > #a(100px); // 父元素不能加 括号
  #card > .c;
}
#main {
  #card .d();
}
#con {
  //不得单独使用命名空间的方法
  //.d() 如果前面没有引入命名空间 #card ,将会报错

  #card; // 等价于 #card();
  .d(20px); //必须先引入 #card
}

编译结果👇:

#wrap {
  height: 100px;
  color: #fff;
}
#main {
  width: 300px;
}
#con {
  background: #723232;
  width: 20px;
}
#con .c {
  color: #fff;
}

要点🎉:

  • 在 CSS 中> 选择器,选择的是 儿子元素,就是 必须与父元素 有直接血源的元素。
  • 在引入命令空间时,如使用 > 选择器,父元素不能加 括号。
  • 不得单独使用命名空间的方法 必须先引入命名空间,才能使用 其中方法。
  • 子方法 可以使用上一层传进来的方法

作用域

在前面变量那章提过作用域了,实际上Less中的作用域也确实和编程语言的作用域类似。作用域可以理解为可以被访问的区域。当编译器解析到一个变量或混合时,会先从当前范围开始查找,也就当前所在的“ { } ”,找不到再去外层也就是父级的作用域开始查找,依次类推。

@color: pink;
.bg {
  background-color: @color; // 1 pink
  a {
    @color: green;
    background-color: @color; // 2 red
    @color: red;
  }
}
div {
  background-color: @color; // 3 pink
}

编译结果👇:

.bg {
  background-color: pink;
}
.bg a {
  background-color: red;
}
div {
  background-color: pink;
}

解析🚀:

  • 1 为pink,首先在.bg的作用域中查找,它只能看见 a 但是看不见a里面,因为那是下一层了,我们只能往上找不能往下找啊,怎么能找到别人家里去了呢,于是它发现自己家没有定义,那就去找爸爸。也就是外层定义的pink。
  • 2 为red,首先在 a 里查找,发现有两次定义,找离自己最近的一次,第一次为green,第二次为red,然后变量会提到a作用域里面的前面,所以为red。
  • 3 为pink这个不必详解了吧,直接就在自己家里找了。

引入

@import用于从其他样式表导入样式,可以根据文件扩展的不同来不同地处理语句

语法:@import " ×××" ;里面为需要引入less文件的相对路径

引入less文件

我们可以在当前文件的任意位置引入一个或多个.less文件,然后在这个文件中的所有变量都可以在当前 less 文件中使用,导入less文件可省略后缀

  1. 在当前目录下创建comment.less:
@font-size: 50px;
html {
  font-size: @font-size;
}
  1. 引入
@import "common";
div{
    font-size: @font-size;
}

编译结果👇:

html {
  font-size: 50px;
}
div {
  font-size: 50px;
}

引入css文件

引入css文件会被原样输出到编译的文件中。因为默认是less所以后缀不能省略,并且引入的css文件不能进行混合。

  1. 在当前目录下创建comment.css:
.bg{
    background-color: pink;
}
  1. 引入
@import "common.css";
.div{
    .bg;    		// 报错 不能进行混合
}

引入可带参数

在引入的时候我们可以带参数来实现不同的引入效果。

参数格式解释
once@import (once) "com"默认,只包含一次
reference@import (reference) "com"使用Less文件但不输出
inline@import (inline) "com.less"在输出中包含源文件但不加工它,不能使用其变量
less@import (less) "com"将文件作为Less文件对象,无论是什么文件扩展名
css@import (css) "com"将文件作为CSS文件对象,无论是什么文件扩展名
multiple@import (mulitiple) "com"允许引用多次相同文件名的文件

注意🎉:

  • 引入了的CSS文件不能进行混合;
  • reference参数使用后可以使用被引入文件的的变量与混合但是被引入的less文件里定义的类与混合不会再被输出,这样就不用一个一个加小括号了,适用于写通用的less文件来供其他less文件使用变量和混合;
  • 使用inline参数,会直接输出其中的类与混合,不能在引入文件中使用其中的变量与混合,适合于书写公共样式,来直接使用;
  • 使用多少次multiple参数引入相同的文件,就会输出多少次(每引入一次就输出一次)。

示例🌰:

common.less:

@color:pink;
.bg{
    background-color: @color;
}
  1. 默认 once
@import (once) "common";
@import (once) "common"; // 这次引入会被忽略

输出(和普通引入一次时结果一致):

.bg {
  background-color: pink;
}
  1. reference
@import (reference) 'common';
div {
  color: @color;
}

输出(只引用了@color,不编译其余内容):

div {
  color: pink;
}
  1. inline
@import (inline) 'common.less';

输出(会直接输出其中的类与混合):

@color: pink; // 报错 因为使直接输出 在css中不能这样定义 所以报错
.bg {
  background-color: @color;  // 报错 property value expected
}
  1. multiple
@import (multiple) "common";
@import (multiple) "common";

输出(同名也允许多次导出):

.bg {
  background-color: pink;
}
.bg {
  background-color: pink;
}

关键字(important)

!important关键字:在调用的混合集后面追加!important关键字,可以使混合集里面的所有属性都继承!important

.bg() {
  width: 200px;
  height: 200px;
}
div {
  .bg();
}
div {
  .bg() !important;
}

编译结果👇:

div {
  width: 200px;
  height: 200px;
}
div {
  width: 200px !important;
  height: 200px !important;
}

条件表达式(Guards)

当需要根据表达式,而不是参数的值或数量来进行匹配时,就需要用到条件表达式了。

Less中使用关键字when来实现条件判断,表达式中可以使用比较运算符逻辑运算符、或检查函数来进行条件判断。

比较运算符

有:>,>=,<,=<,=, ture;

.mixin(@width) when (@width <= 360px) {
  width: @width;
  height: 100%;
  background-color: pink;
}
.mixin(@width) when (@width > 360px) {
  width: @width;
  height: 100%;
  background-color: black;
}
div {
  .mixin(500px);
}

编译结果(匹配到第二个条件)👇:

div {
  width: 500px;
  height: 100%;
  background-color: black;
}

还可以使用关键字true,它表示布尔真,以下两个mixin是相同的:

  • truth (@a) when (@a) { ... }
  • truth (@a) when (@a = true) { ... }

在Less中,只有true表示布尔真,关键字true以外的任何值,都被视为布尔假。如:

.div{
    .truth(40);   	// 不会匹配上面的任何定义
}

注意when后的条件表达式可以是多个表达式,多个表达式之间使用逗号相隔,若其中任何一个为true,则匹配为成功,相当于“ 或 ” 的关系。

逻辑运算符

Less中,表达式之间也可以使用andnot来进行逻辑运算。

  • and 连接的表达式需都为 true 才能匹配成功。
  • not 表示否定的意思
// 传入的参数大于200px 且 小于 500px
.mixin(@width) when (@width > 200px) and (@width < 500px) {
  width: @width;
  height: 100%;
  background-color: pink;
}
// 传入的参数 不小于500px 且 大于0
.mixin(@width) when not(@width < 500px) and (@width > 0) {
  width: @width;
  height: 100%;
  background-color: black;
}
div {
  .mixin(500px);
}

编译结果(匹配到第二个条件)👇:

div {
  width: 500px;
  height: 100%;
  background-color: black;
}

类型检查函数

可以基于值的类型来匹配函数

类型检查函数说明
iscolor是否为颜色值
isnumber是否为数值
isstring是否为字符串
iskeyword是否为关键字
isurl是否为URL字符串

是则为 true 则执行匹配的内容,用于匹配相同的类型。

.mixin(@a) when (iscolor(@a)) {
  background-color: @a;
}
.mixin(@a) when (isnumber(@a)) {
  width: @a;
  height: @a;
}
div {
  .mixin(100%);
  .mixin(pink);
}

编译结果👇:

div {
  width: 100%;
  height: 100%;
  background-color: pink;
}

单位检查函数

单位检查函数说明
ispixel是否为像素单位
ispercentage是否为百分比
isem是否为em单位
isunit是否为单位

同类型检查函数,用于匹配相同的单位。

.mixin(@a) when (ispixel(@a)) {
  border: @a solid pink;
}
.mixin(@a) when (ispercentage(@a)) {
  width: @a;
  height: @a;
}
div {
  .mixin(100%);
  .mixin(1px);
}

编译结果👇:

div {
  width: 100%;
  height: 100%;
  border: 1px solid pink;
}

循环(loop)

在Less中,混合可以调用它自身,这样,当一个混合递归调用自己再结合Guards表达式和模式匹配这两个特性,就可以写出循环结构

.loop(@counter) when (isnumber(@counter)) and (@counter > 0) {
    .loop(@counter - 1);
    .div@{counter}{
        width: 10 * @counter;
        height: 10 * @counter;
    }
}
li{
    .loop(3);
}

编译结果👇:

li .div1 {
  width: 10;
  height: 10;
}
li .div2 {
  width: 20;
  height: 20;
}
li .div3 {
  width: 30;
  height: 30;
}

合并属性

它是Less的一个特性,它允许使用单个属性从多个属性中为逗号空格分隔列表添加值。 它可以用于背景和变换属性。

逗号分割合并的属性( + )

在需要合并的属性的: 前面加上+就可以完成合并,合并以, 分割属性。

.mixin() {
  // name 为 in 的动画
  animation+: in 3s;
}
div {
  .mixin();
  // name 为 out 的动画
  animation+: out 3s;
}

编译结果👇:

div {
  animation: in 3s, out 3s;
}

空格分割合并的属性( +_ )

在需要合并的属性的:前面加上+_ 就可以完成合并,合并以空格分割属性。

.mixin() {
  border+_: 1px solid;
}
div {
  .mixin();
  border+_: steelblue;
}

编译结果👇:

div {
  border: 1px solid steelblue;
}

继承(extend)

:extend是一个伪类,使用它的选择器,将和它引用的选择器一起使用它引用的选择器的样式

extend 关键字的使用

.animation {
  transition: all 0.3s ease-out;
  .hide {
    transform: scale(0);
  }
}
#main {
  &:extend(.animation);
}
#con {
  &:extend(.animation .hide);
}

也可以直接将其使用在选择器后:

#main:extend(.animation) {}
#con:extend(.animation .hide) {}

编译结果👇:

.animation,
#main {
  transition: all 0.3s ease-out;
}
.animation .hide,
#con {
  transform: scale(0);
}

all 全局搜索替换

使用选择器匹配到的 全部声明。

#main {
  width: 200px;
}
#main {
  &:after {
    content: 'Less is good!';
  }
}
#wrap:extend(#main all) {
}

编译结果👇:

#main,
#wrap {
  width: 200px;
}
#main:after,
#wrap:after {
  content: 'Less is good!';
}

函数库

Less的函数库中包含杂项函数(其他函数)、字符串函数、列表函数(长度相关函数)、数学函数、类型函数、颜色定义函数、颜色通道函数、颜色操作函数(颜色值运算函数)、颜色值混合函数。

杂项函数(其他函数)

函数说明
color()解析颜色,将代表颜色的字符串转换为16进制颜色值
image-size()从文件中获取图像的尺寸
image-width()从文件中获取图像的宽度
image-height()从文件中获取图像的高度
convert()将数字从一个单位转换为另一个单位
data-uri()将一个资源内嵌到样式文件,如果开启了ieCompat选项,而且资源文件体积过大,或者在浏览器中使用,则会使用url()进行回退。如果没有指定MIME,则Node.js会使用MIME包来决定正确的MIME
default()只能在边界条件中使用,没有匹配到其他自定义函数(mixin)的时候返回true,否则返回false
unit()删除或更改尺寸单位
get-unit()返回数字的单位
svg-gradient()生成多级svg渐变

字符串函数

函数说明
escape()将输入字符串中的 url 特殊字符进行编码处理
e()CSS转义,也可以用 ~ “ 值 ”符号代替
%()格式化一个字符串
replace()用另一个字符串替换文本

长度相关函数

函数说明
length()返回值列表中的元素数。
extract()返回列表中指定位置的值。

数学函数

函数说明
ceil()向上取整
floor()向下取整
percentage()将浮点数转换为百分比
round()取整和四舍五入
sprt()计算一个数的平方根,原样保持单位
abs()计算数字的绝对值,原样保持单位
sin()正弦函数
asin()反正弦函数
cos()余弦函数
acos()反余弦函数
tan()正切函数
atan()反正切函数
pi()返回π(pi)
pow()乘方运算
mod()取余运算
min()最小值运算
max()最大值运算

类型函数

函数说明
isnumber()如果值是数字,返回真(true),否则返回假(false)。
isstring()如果值是一个字符串,返回真(true),否则返回假(false)。
iscolor()如果值是一个颜色,返回真(true),否则返回假(false)。
iskeyword()如果值是一个关键字,返回真(true),否则返回假(false)。
isurl()如果值是一个url地址,返回真(true),否则返回假(false)。
ispixel()如果值是带px单位的数字,返回真(true),否则返回假(false)。
issem()如果值是带em单位的数字,返回真(true),否则返回假(false)。
ispercentage()如果值是一个带%单位的数字,返回真(true),否则返回假(false)。
isunit()如果值是带指定单位的数字,返回真(true),否则返回假(false)。

颜色值定义函数

函数说明
rgb()通过十进制红、绿、蓝(RGB)创建不透明的颜色对象。
rgba()通过十进制红、绿、蓝(RGB),以及alpha四种值(RGBA)创建带alpha透明的颜色对象。
argb()创建格式为#AARRGGBB的十六进制颜色 ,用于IE滤镜,.net和安卓开发。
hls()通过色相,饱和度,亮度(HLS)三种值创建不透明的颜色对象。
hsla()通过色相,饱和度,亮度,以及alpha四种值(HLSA)创建带alpha透明的颜色对象。
hsv()通过色相,饱和度,色调(HSV)创建不透明的颜色对象。
hsva()通过色相,饱和度,亮度,以及alpha四种值(HSVA)创建带alpha透明的颜色对象。

颜色值通道提取函数

函数说明
hue()从HSL色彩空间中提取色相值。
saturation()从HSL色彩空间中提取饱和度。
lightness()从HSL色彩空间中提取亮度值。
hsvhue()从HSV色彩空间中提取色相值。
hsvsaturation()从HSV色彩空间中提取饱和度值。
hsvvalue()从HSV色彩空间中提取色调值。
red()提取颜色对象的红色值。
green()提取颜色对象的绿色值。
blue()提取颜色对象的蓝色值。
alpha()提取颜色对象的透明度。
luma()计算颜色对象luma的值(亮度的百分比表示法)。
luminance()计算没有伽玛校正的亮度值。

颜色值运算函数

函数说明
saturate()增加一定数值的颜色饱和度。
desaturate()降低一定数值的颜色饱和度。
lighten()增加一定数值的颜色亮度。
darken()降低一定数值的颜色亮度。
fadein()降低颜色的透明度(或增加不透明度),令其更不透明。
fadeout()增加颜色的透明度(或降低不透明度),令其更透明。
fade()给颜色(包括不透明的颜色)设定一定数值的透明度。
spin()任意方向旋转颜色的色相角度。
mix()根据比例混合两种颜色,包括计算不透明度。
greyscale()完全移除颜色的饱和度,与desaturate(@color,100%)函数效果相同。
contrast()旋转两种颜色相比较,得出哪种颜色的对比度更大就倾向于对比度最大的颜色。

颜色值混合函数

函数说明
multiply()分别将两种颜色的红绿蓝三种值做乘法运算,然后再除以255,输出结果更深的颜色(对应ps中的“变暗/正片叠底”)。
screen()与multiply函数效果相反,输出结果更亮的颜色。(对应ps中“变亮/滤色”)。
overlay()结合multiply与screen两个函数的效果,令浅的颜色更浅,深的颜色更深(对应ps中的叠加),输出结果由第一个颜色参数决定。
softlight()与overlay函数效果相似,只是当纯黑色或纯白色作为参数时输出结果不会是纯黑色或纯白色(对应ps中的“柔光”)。
hardlight()与overlay函数效果相似,不过由第二个颜色参数决定输出颜色的亮度或黑度,而不是第一个颜色参数决定(对应ps中“强光/亮光/线性光/点光”)。
difference()从第一个颜色值中减去第二个(分别计算RGB三种颜色值),输出结果更深的颜色(对应ps中“差值/排除”)。
exclusion()效果与difference函数效果相似,只是输出结果差别更小(对应ps中“差值/排除”)。
average()分别对RGB三个颜色值取平均值,然后输出结果。
negation()与difference函数效果相反,输出结果是更亮的颜色。(效果相反不代表做加法运算)。

进一步阅读

你现在知道的已经足够上手项目了!随着学习的深入,你将能够使代码变得更好。这里建议你接下来阅读以下内容以获取更多相关知识:

Less中文官网

Less英文官网

参考文章 📜

❤️ 学习Less-看这篇就够了

❤️ Less从入门到精通

扩展 🏆

如果你觉得本文对你有帮助,可以查看我的其他文章❤️:

👍 10个简单的技巧让你的 vue.js 代码更优雅🍊

👍 vue3实战笔记 | 快速入门🚀

👍 零距离接触websocket🚀

👍 Web开发应了解的5种设计模式

👍 Web开发应该知道的数据结构

👍 如何在JavaScript中获取屏幕,窗口和网页大小