Less 预处理器
一、是什么
Less 是一种动态样式语言,属于 CSS 预处理语言的一种,它使用类似 CSS 的语法,为 CSS 的赋予了动态语言的特性,如变量、继承、运算、函数等,更方便 CSS 的编写和维护。

Less(Less 编辑器)是开源的,其第一个版本由 Ruby 写成,但在后续的版本当中,Ruby 逐渐被替换为 JavaScript。受益于 JavaScript,LESS 可以在客户端上运行(IE6+、Webkit、Firefox),也可以在服务端运行(Node.js、Rhino)。
二、编译 less
1. 使用 less.js 编译 less
<style type="text/less">
@fcolor: #900;
@bcolor: #099;
@len: 1000px;
#box {
width: @len;
height: (@len/4);
color: @fcolor;
background: @bcolor;
padding: 20px;
}
</style>
<script src="./less.js"></script>2. VSCode 插件自动编译 less
1)vscode 安装扩展 "Easy Less"。
2)创建扩展名是 .less 的文件,在文件中写 less 代码; Easy Less 会自动编译成同名的 CSS; 每次保存都会自动编译。
3)html 中使用 link 引入 css 文件。
3. 第三方编译工具 koala
koala (考拉) 官网:http://koala-app.com/index-zh.html
4. nodejs

安装
npm install less -g使用
lessc bootstrap.less bootstrap.css三、语法
1. 注释(Comments)
/* 一个块注释
* style comment!
*/
@var: red;
// 这一行被注释掉了!
@var: white;// 不会编译到 CSS 文件中。/**/ 会编译到 CSS 中。
2. 变量(Variables)
① 定义变量
定义变量的一般形式:
@变量名:值;
// 例子
@len: 600px;
@master-red: #900;
@prop:background-position;如果变量的值有特殊符号:
@变量名:~"值";
// 例子
@min768: ~"min-width:768px";
@sel01: ~".news li";② 使用变量
将变量作为属性值使用(大部分应用场景)
// 直接使用 @变量名
width: @len;
color: @master-green;
background: @master-red;
border: 1px solid @master-green;
@media (@min768) {
.container {
width: 100%;
}
}将变量作为属性名或者选择器使用
// @{变量名}
.box {
// 变量作为属性名
@{prop}: 10px 10px;
}
// 变量名作为选择器
@{sel01} {
width: @len;
height: (@len/2);
}less 中,变量名没有命名规范。
3. 混合(Mixin)
混合(Mixin)是一种将一组属性从一个规则集包含(或混入)到另一个规则集的方法。类似于 JavaScript 中的函数。目的是提高代码的重用性。
在 Less 中,可以使用类(class)或者ID(#ids)作为 mixin(混合)。
基本使用
// 在 less 中,这个既是类选择器,也是混合
.bordered {
border-top: dotted 1px black;
border-bottom: solid 2px black;
}#menu a {
color: #111;
// 当作混合使用
.bordered();
}
.post a {
color: red;
// 当作混合使用
.bordered();
}.bordered 类所包含的属性就将同时出现在 #menu a 和 .post a 中了。
这种缺点是 .bordered 也会在 CSS 中以类选择器出现。比较合理的是在混合后面加上括号。
① 混合
定义混合
.center-box01() {
position: absolute;
width: 400px;
height: 300px;
left: 50%;
top: 50%;
margin-left: -200px;
margin-top: -150px;
}使用混合
.item {
// 调用混合
.center-box01();
}
.news li {
// 调用混合
.center-box01();
// 其他样式
background: #900;
border: 1px solid #999;
}② 带参数的混合
定义带参数的混合
// 定义混合 有参数
.center-box02(@width, @height) {
position: absolute;
width: @width;
height: @height;
left: 50%;
top: 50%;
margin-left: -(@width/2);
margin-top: -(@height/2);
}使用有参数的混合
// 调用有参数的混合 按照顺序传参数
.center-box02(600px,500px);
// 调用有参数的混合 按照名字传参
.center-box02(@height:600px, @width:700px);③ 参数有默认值的混合
// 定义混合 参数设置默认值
// 有默认值的参数在后面
// 可以按照顺序传参,也可以按照名字传参
.center-box03(@width, @height:800px) {
position: absolute;
width: @width;
height: @height;
left: 50%;
top: 50%;
margin-left: -(@width/2);
margin-top: -(@height/2);
}
// 有默认值的参数在前面后面都可以
// 只能按照名字传参
.center-box04(@width:1200px, @height) {
position: absolute;
width: @width;
height: @height;
left: 50%;
top: 50%;
margin-left: -(@width/2);
margin-top: -(@height/2);
}④ @arguments
// @arguments 获取参数列表
.box-shadow(@x, @y, @b, @o, @color) {
-webkit-box-shadow: @arguments;
-moz-box-shadow: @arguments;
-o-box-shadow: @arguments;
box-shadow: @arguments;
}
.box {
width: 400px;
height: 300px;
background: #900;
.box-shadow(3px, 10px, 15px, 0px, #ccc);
}4. Less 条件判断
.triangle(@border-width, @color, @direction) when (@direction=up) {
width: 0;
height: 0;
border-style: solid;
border-width: @border-width;
border-color: transparent transparent @color transparent;
}
.triangle(@border-width, @color, @direction) when (@direction=down) {
width: 0;
height: 0;
border-style: solid;
border-width: @border-width;
border-color: @color transparent transparent transparent;
}
.triangle(@border-width, @color, @direction) when (@direction=left) {
width: 0;
height: 0;
border-style: solid;
border-width: @border-width;
border-color: transparent @color transparent transparent;
}
.triangle(@border-width, @color, @direction) when (@direction=right) {
width: 0;
height: 0;
border-style: solid;
border-width: @border-width;
border-color: transparent transparent transparent @color;
}5. 导入(Importing)
“导入”的工作方式和你预期的一样。你可以导入一个 .less 文件,此文件中的所有变量就可以全部使用了。如果导入的文件是 .less 扩展名,则可以将扩展名省略掉:
@import "library"; // library.less
@import "typo.css";6. 嵌套(Nesting)
Less 提供了使用嵌套(nesting)代替层叠或与层叠结合使用的能力。
① 基本使用 (层级选择器)
.news {
li {}
>li {}
+li {}
~li {}
}编译为:
.news {}
.news li {}
.news > li {}
.news + li {}
.news ~ li {}② & 符号应用 (交集选择器组合)
& 表示当前选择器的父级。
.item {
&:hover {}
&.active {}
}编译为:
.item {}
.item:hover {}
.item.active {}③ 媒体查询的嵌套
@规则嵌套和冒泡
@ 规则(例如 @media 或 @supports)可以与选择器以相同的方式进行嵌套。@ 规则会被放在前面,同一规则集中的其它元素的相对顺序保持不变。这叫做冒泡(bubbling)。
.component {
width: 300px;
@media (min-width: 768px) {
width: 600px;
@media (min-resolution: 192dpi) {
background-image: url(/img/retina2x.png);
}
}
@media (min-width: 1280px) {
width: 800px;
}
}编译为:
.component {
width: 300px;
}
@media (min-width: 768px) {
.component {
width: 600px;
}
}
@media (min-width: 768px) and (min-resolution: 192dpi) {
.component {
background-image: url(/img/retina2x.png);
}
}
@media (min-width: 1280px) {
.component {
width: 800px;
}
}④ 混合和嵌套结合
可以将伪选择器(pseudo-selectors)与混合(mixins)一同使用。下面是一个经典的 clearfix 技巧,重写为一个混合(mixin)。
.clearfix() {
&::after {
content: "";
display: block;
clear:both;
}
}7. 运算(Operations)
① 算术运算符
算术运算符 +、-、*、/ 可以对任何数字、颜色或变量进行运算。如果可能的话,算术运算符在加、减或比较之前会进行单位换算。计算的结果以最左侧操作数的单位类型为准。如果单位换算无效或失去意义,则忽略单位。无效的单位换算例如:px 到 cm 或 rad 到 % 的转换。
如果两个操作数单位不一致,结果使用第一个操作数的单位;如果只有一个操作数有单位,结果就使用该单位。
注意:除运算需要使用小括号。
// 所有操作数被转换成相同的单位
@conversion-1: 5cm + 10mm; // 结果是 6cm
@conversion-2: 2 - 3cm - 5mm; // 结果是 -1.5cm
// conversion is impossible
@incompatible-units: 2 + 5px - 3cm; // 4px
// example with variables
@base: 5%;
@filler: @base * 2; // 结果是 10%
@other: @base + @filler; // 结果是 15%乘法和除法不作转换。因为这两种运算在大多数情况下都没有意义,一个长度乘以一个长度就得到一个区域,而 CSS 是不支持指定区域的。Less 将按数字的原样进行操作,并将为计算结果指定明确的单位类型。
@base: 2cm * 3mm; // 结果是 6cm你还可以对颜色进行算术运算:
@color: (#224488 / 2); // 结果是 #112244
background-color: #112244 + #111; // 结果是 #223355② calc() 特例
为了与 CSS 保持兼容,calc() 并不对数学表达式进行计算,但是在嵌套函数中会计算变量和数学公式的值。
@var: 50vh/2;
width: calc(50% + (@var - 20px)); // 结果是 calc(50% + (25vh - 20px))8. 函数(Functions)
Less 内置了多种函数用于转换颜色、处理字符串、算术运算等。
percentage() 计算百分比
mod() 取余运算
lighten() 颜色调高亮度
darken() 颜色调低亮度函数的用法非常简单。下面这个例子将介绍如何利用 percentage 函数将 0.5 转换为 50%,将颜色饱和度增加 5%,以及颜色亮度提高 25% 并且色相值增加 8:
@base: #f04615;
@width: 0.5;
.class {
// percentage(@width) 返回的是 50%,即.class的宽度为 50%。
width: percentage(@width);
// saturate(@base, 5%) 会将 @base 颜色的饱和度提高 5%。所以,这会使得原本的红色变得更鲜艳一些。
color: saturate(@base, 5%);
/*
lighten(@base, 25%) 会将 @base 颜色的亮度提高 25%,
然后 spin() 函数会将这个亮度提高后的颜色在色轮上旋转 8 度。
这样,背景色就会是一个比原红色更亮且稍微偏向其他颜色的新颜色。
*/
background-color: spin(lighten(@base, 25%), 8);
}官方函数文档:https://less.bootcss.com/functions
9. 转义(Escaping)
转义(Escaping)允许你使用任意字符串作为属性或变量值。任何 ~"anything" 或 ~'anything' 形式的内容都将按原样输出,除非 interpolation。
@min768: ~"(min-width: 768px)";
.element {
@media @min768 {
font-size: 1.2rem;
}
}编译为:
@media (min-width: 768px) {
.element {
font-size: 1.2rem;
}
}注意,从 Less 3.5 开始,可以简写为:
@min768: (min-width: 768px);
.element {
@media @min768 {
font-size: 1.2rem;
}
}在 Less 3.5+ 版本中,许多以前需要“引号转义”的情况就不再需要了。
interpolation 是什么?
在 Less 中,插值(Interpolation)是一种特性,允许你在字符串中嵌入变量,并在运行时将这些变量替换为它们的值。
插值的语法是 @{variableName},其中 variableName 是你要插入的变量的名称。当 Less 解析这个字符串时,它会找到所有的插值表达式,并用相应的变量值替换它们。
@myColor: 'red';
.myClass {
color: ~"@{myColor}";
}在这个例子中,~"@{myColor}" 是一个插值表达式。当 Less 解析这个表达式时,它会找到 @{myColor},并用 @myColor 变量的值(即 'red')替换它。所以,生成的 CSS 代码是:
.myClass {
color: red;
}10. 命名空间和访问符
用途:组织和重用代码。
在 Less 中,可以创建一个命名空间,然后在这个命名空间内定义一些混合(mixin)或者选择器。在这个例子中,#bundle() 就是一个命名空间,它内部定义了 .button、.tab 和 .citation 三个混合。
#bundle() {
.button {
display: block;
border: 1px solid black;
background-color: grey;
&:hover {
background-color: white;
}
}
.tab { ... }
.citation { ... }
}然后,就可以在其他地方通过#bundle.button()的形式来调用这个混合。这就像是在访问一个命名空间内的成员。在这个例子中,#header a 选择器中调用了 #bundle.button() 混合,所以 #header a 会获得 .button 混合定义的所有样式。
#header a {
color: orange;
#bundle.button(); // 还可以书写为 #bundle > .button 形式
}注意,也可以使用 #bundle > .button 的形式来调用混合,这和 #bundle.button() 是等价的。
11. 映射(Maps)
用途:组织和使用值。
从 Less 3.5 版本开始,还可以将混合(mixins)和规则集(rulesets)作为一组值的映射(map)使用。
在 Less 中,可以创建一个混合(mixin),然后在这个混合内定义一些变量。在这个例子中,#colors() 就是一个混合,它内部定义了 primary 和 secondary 两个变量。
然后,就可以在其他地方通过 #colors[primary] 的形式来访问这个混合内的变量。这就像是在访问一个映射的键值对。在这个例子中,.button 选择器中访问了 #colors[primary] 和 #colors[secondary],所以 .button 的 color 和 border 会获得这两个变量的值。
#colors() {
primary: blue;
secondary: green;
}
.button {
color: #colors[primary];
border: 1px solid #colors[secondary];
}编译为:
.button {
color: blue;
border: 1px solid green;
}四、其他
1. 作用域(Scope)
Less 中的作用域。首先在本地查找变量和混合(mixins),如果找不到,则从“父”级作用域继承。
@var: red;
#page {
@var: white;
#header {
color: @var; // white
}
}混合(mixin)和变量的定义不必在引用之前事先定义。因此,下面的 Less 代码示例和上面的代码示例是相同的:
@var: red;
#page {
#header {
color: @var; // white
}
@var: white;
}