less使用指南

爱吃猪头爱吃肉

Less 地址

加 * 为使用重点看一下

1、前言

借鉴知乎大佬文章,便于更加方便查看😍

2、导入

1
2
@import "library"; // library.less
@import "typo.css";

2.1 * 导入关键字

导入关键字使用形式如 @import (optional, reference) "foo.less"

所包含的关键字有:

  1. reference: 导入的样式文件将作为参考,其所包含的选择器将不会呈现在输出文件,却可以使用 mixin 混入或 extend 扩展将原选择器的样式添加到新的选择器中。reference 的应用场景如,@import (reference) bootstrap.less 样式,使用混入或扩展关键字只将 .navbar all 相关选择器的样式输出。推想其实现如,以内存形式缓存编译后的样式文件,被引用时才注入到输出文件中。
  2. inline: 全量复制 css 文件,不作处理(less 在某些地方不支持注释;且在不修改 css 的情形下,less 也不支持全部的 css hacks)。
  3. less: 以 less 文件形式处理导入的样式文件,不管文件扩展名。
  4. css: 以 css 文件形式处理导入的样式文件,不管文件扩展名。
  5. once: 样式文件只导入一次,默认。
  6. multiple:样式文件导入多次。
  7. optional: 样式文件不存在时不会报错。

3、嵌套规则

使用嵌套形式书写样式文件时,& 表示父选择器。

less 将使用父选择器名替换 &。特殊的,使用 & 能改变选择器的顺序;当有多个父选择器时,& 依次解析为这几个父选择器。

推想其实现如,以块 {} 为编译单元,以 selectors 缓存 {} 前选择器,以 content 缓存 {} 内容并作解析,将样式写入 output;然后递归调用前述过程,传入父 selectors, content,解析子块时再将父 selector 添加到子 selector 前,将样式写入 output。嵌套规则以树形结构组织,但样式写入 output 时为扁平化结构。单个 & 可以使用父 selector;多个 &,可先构建两维数组,每个数组项为父 selector 的有序列表,然后遍历两维数组进行替换。若 & 在选择器的尾部,编译时无需在子选择器前添加父选择器,而只将 & 替换为父选择器。

  • 多个父选择器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// input
p, a {
& + & {
border-top: 0;
}
}

// output
p + p,
p + a,
a + p,
a + a {
border-top: 0;
}
  • 改变选择器的顺序
1
2
3
4
5
6
7
8
9
10
11
12
13
// input
.header {
.menu {
.no-borderradius & {
background-image: url('images/button-background.png');
}
}
}

// output
.no-borderradius .header .menu {
background-image: url('images/button-background.png');
}

4、变量

less 中变量使用 @variableName: variableValue 形式声明;@variableName 或 @{variableName} 形式使用。变量可用于选择器的名称,样式属性的名称,样式属性的值,url,import 语句等。

less 允许使用变量去定义另一个变量的名称,即 @@variablename2 形式声明变量 variablename1。

less 允许先使用变量,再声明变量。推想其实现如,同 js 一样会将声明提前,并保留在内存中,以精确的值替换掉使用的变量,文件解析完成后,再释放内存。

变量有作用域,就近定义的优先。推想其编译过程,块将解析为函数,当在块中再度遇到相同的变量名,注入函数的实参就会被改变,最终输出也因而改变。其实现可能譬如模板引擎。

变量的一大用途包含,通过变量设置网页样式的主题。

1
2
3
4
5
6
7
8
@var: red;

#page {
@var: white;
#header {
color: @var; // white
}
}

4.1 变量与混合

变量可以存储分离的规则集,其下可包含属性、嵌套规则集、变量声明、混合等。分离的规则集在块 {} 中以函数形式使用,该块内就可以使用分离的规则集内所声明的变量、样式属性和混合。

推想其实现如,将分离规则集解析为函数,在快内使用时再行植入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// input
@detached-ruleset: {
.mixin() {
font-family: "Comic Sans MS";
background-color: #AA86EE;
}
};

.cont {
@detached-ruleset();
.mixin();
}

// output
.cont {
font-family: "Comic Sans MS";
background-color: #AA86EE;
}

5、操作符

算数运算符 +, -, *, / 可作用于变量、颜色、数值,less 将尝试获得单位。推想其实现,首先将变量替换为实际的值,然后匹配到操作符,解析操作符前后数值的单位并获得最终单位,使用最终单位修正数值,数值计算并输出。

1
2
3
4
5
6
@conversion-1: 5cm + 10mm; // 输出 6cm
@conversion-2: 2 - 3cm - 5mm; // 输出 1.5cm
@incompatible-units: 2 + 5px - 3cm; // 输出 4px
@base: 5%;
@filler: @base * 2; // 输出 10%
@other: @base + @filler; // 输出 15%

6、* 转义

任何 ~”anything” 或 ~’anything’ 语句内,单双引号内容都将被保留,可用于规避 ‘//‘, ‘/ /‘被误认为注释。

1
2
3
.weird-element {
content: ~"^//* some horrible but needed css hack";// 输出 content: ^//* some horrible but needed css hack;
}

7、混合

混合能将某个类或 id 选择器中的样式添加到另一个选择器中,其书写形式如 css 中为类或 id 选择器添加样式,其下可包含选择器(当子选择器为类或 id 选择器时,该子选择器构成另一个混合,可以直接使用;这样,父选择器也称为命名空间)。

当 guard 应用于命名空间时,当且仅当 guard 条件返回真值,才能使用由命名空间定义的混合。参见 guard。

使用混合时添加 !important 关键字,混合下所有样式都将添加 !important。

特别,当类或 id 选择器以 () 结尾时,选择器将不会在输出文件中有所表现,而只是在使用时会将样式混入到其他选择器中。() 中可以添加参数(以 ‘,’ 或 ‘;’ 分割参数),使函数具有函数特征,且支持多态。混合函数使用时可以借助参数名指定参数的值,这样就无关参数的位置;且使用时,@arguments 将包含所有参数;参数支持解构语法如 … 或 @rest…。混合函数的参数可以是复杂的样式规则。

在混合函数中声明的变量,可以在使用混合的块中访问。但是块中若有同名变量,以块中声明的变量优先。

推想其实现如,编译结束后类或 id 选择器构成的混合将保留在内存中,对于 () 结尾的选择器将以函数形式保存,使用时调用函数,这样就不会有样式输出。且保留在内存中的函数是在解析到 () 时构建的,这样就使得 less 语法上呈现多态,编译出来的函数可以使用控制语句处理函数体内参数的多态特征。

  • 命名空间,不输出混合。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// input
#bundle() {
.button {
display: block;
border: 1px solid black;
background-color: grey;
&:hover {
background-color: white
}
}
.tab { ... }
.citation { ... }
}

#header a {
color: orange;
#bundle > .button;
}

// output
#header a {
color: orange;
display: block;
border: 1px solid black;
background-color: grey;
&:hover {
background-color: white
}
}
  • 使用 !important
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// input
.foo (@bg: #f5f5f5, @color: #900) {
background: @bg;
color: @color;
}
.important {
.foo() !important;
}

// output
.important {
background: #f5f5f5 !important;
color: #900 !important;
}
  • 混合函数支持多态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// input
.mixin(dark; @color) {
color: darken(@color, 10%);
}
.mixin(light; @color) {
color: lighten(@color, 10%);
}
.mixin(@_; @color) {
display: block;
}

@switch: light;

.class {
.mixin(@switch; #888);
}

// output
.class {
color: #a2a2a2;
display: block;
}
  • 混合函数中定义的变量,可以在使用时引用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// input
.mixin() {
@width: 100%;
@height: 200px;
}

.caller {
.mixin();
width: @width;
height: @height;
}

// output
.caller {
width: 100%;
height: 200px;
}

8、extend

  1. 扩展 :extend 是 less 提供的伪类,使用形式如 .big-bag:extend(.bag) 将使 .big-bag 拥有 .bag 的样式。

使用 all 关键字如 .replacement:extend(.test all),将把 .test 替换为 .replacement,再行输出另一份样式规则。

推想其实现如,selector1:extend(selector2) 伪类前后内容解析为映射形式,在将 selector2 的样式规则赋值给 selector1。

  • all 关键字
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// input
.a.b.test,
.test.c {
color: orange;
}
.test {
&:hover {
color: green;
}
}

.replacement:extend(.test all) {}

// output
.a.b.test,
.test.c,
.a.b.replacement,
.replacement.c {
color: orange;
}
.test:hover,
.replacement:hover {
color: green;
}

8.1 扩展和指令

若 extend 伪类在 @media 指令中定义,那么 less 将在 @media 指令内查找匹配的选择器。若 extend 伪类在顶层定义,less 将能匹配到所有 @media 指令中的选择器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// input
@media print {
.screenClass:extend(.selector) {} // extend inside media
.selector { // this will be matched - it is in the same media
color: black;
}
}

// output
@media print {
.selector,
.screenClass { /* ruleset inside the same media was extended */
color: black;
}
}

9、嵌套指令

嵌套指令会冒泡到顶层。对于条件指令如 @Media, @supports, @document 等,条件指令上的父选择器会被植入条件指令内;对于非条件指令如 @font-face, @keyframes 等,条件指令上的父选择器会被忽略。

  • 条件指令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// input
.screen-color {
@media screen {
color: green;
@media (min-width: 768px) {
color: red;
}
}
}

// output
@media screen {
.screen-color {
color: green;
}
}
@media screen and (min-width: 768px) {
.screen-color {
color: red;
}
}
  • 非条件指令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// input
#a {
color: blue;
@font-face {
src: made-up-url;
}
}

// output
#a {
color: blue;
}
@font-face {
src: made-up-url;
}

10、guard(when循环)

guard 用于指定条件,在满足该条件时,才会有样式输出。使用形式如 when (@var = value),即当 @var 变量或参数等于 value 时,才满足条件。when 条件内可包含比较运算符如 =, <, >, <=, >=,以及逻辑运算符 and, and not,内置的类型检查函数如 iscolor, isnumber, isstring, iskeyword, isurl, ispixel, ispercentage, isem, isunit。

当使用 guard 递归构建 mixin 时,可以形成循环。

  • 逻辑运算符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// input
.mixin (@a) when (@a > 50%) and (@a > 5px){
font-size: 14px;
}
.mixin (@a) when not (@a < 50%) and not (@a < 5px){
font-size: 20px;
}
.mixin (@a) {
color: @a;
}

.class1 { .mixin(#FF0000) }
.class2 { .mixin(#555) }

// output
.class1 {
font-size: 20px;
color: #FF0000;
}
.class2 {
font-size: 20px;
color: #555;
}
  • 循环
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// input
.cont(@count) when (@count > 0) {
.cont((@count - 1)); // 递归调用
width: (25px * @count);
}
div {
.cont(3);
}

// output
div {
width: 25px;
width: 50px;
width: 75px;
}

11、合并

  • 使用 ‘,’ 串联多个样式属性
1
2
3
4
5
6
7
8
9
10
11
12
13
// input
.myfunc() {
box-shadow+: 5px 5px 5px grey;
}
.class {
.myfunc();
box-shadow+: 0 0 5px #f78181;
}

// output
.class {
box-shadow: 5px 5px 5px grey, 0 0 5px #f78181;
}
  • 使用空格串联多个样式属性
1
2
3
4
5
6
7
8
9
10
11
12
13
// input
.mixin() {
transform+_: scale(1);
}
.class {
.mixin();
transform+_: rotate(2deg);
}

// output
.class {
transform: scale(1) rotate(2deg);
}

12、函数

推想其实现如,由 less 提供上下文环境,并通过该上下文环境输出内置函数。颜色函数的实现是笔者鞭长莫及的。

1
2
3
4
5
6
7
8
@base: #f04615;
@width: 0.5;

.class {
width: percentage(@width);
color: saturate(@base, 5%);
background-color: spin(lighten(@base, 25%), 8);
}

12.1、其他函数

  1. color: 颜色转换函数。
  2. image-size: 从文件中获取图像的宽度及高度,可作为 image-size 样式的值。
  3. image-width : 从文件中获取图像的宽度。
  4. image-height: 从文件中获取图像的高度。
  5. convert: 单位转换,如 convert(10cm, mm)。
  6. data-uri: 用于嵌入资源,data-uri(url, mimeType)。
  7. unit: 可用于指定单位,unit(dimension, unit)。
  8. get-unit: 可用于获取单位,如 get-unit(30px)。
  9. svg-gradient: 可用于转换颜色,
  10. if: 按条件返回指定的值,if(condition, value1, value2),当 condition 成立时,返回 value1,否则返回 value2。
1
2
3
4
.style {
@style: orange, green 30%, #DAA520;
background-image: svg-gradient(ellipse, @style);
}

12.2、字符串函数

  1. escape: 对特殊字符使用URL编码来对字符串或信息进行编码。
  2. e: 去除字符串的引号。
  3. %: format 函数,用于转化字符串,如 %(string,arguments …)。
  4. replace: 用于替换字符串,如 replace(string, pattern, replacement, flags)。

12.3、列表函数

  1. length: 用于获取列表的长度,如 @list: “audi”, “benz”, “toyota”, “honda”; length(@list)。
  2. extract: 用于获取列表中指定位置的值,如 @list: “audi”, “benz”, “toyota”, “honda”; length(@list, 2)。

12.4、数学函数

  1. ceil: 向上取整。
  2. floor: 向下取整。
  3. percentage: 将浮点数转换为百分比字符串。
  4. round: 四舍五入。
  5. sqrt: 获取平方根。
  6. abs: 取绝对值,如 abs(30ft) 将获得 30ft。
  7. sin, asin, cos, acos, tan, atan: 计算正弦、反正弦等。
  8. pi: 返回 pi 的值。
  9. pow: 计算幂。
  10. mod: 计算首参相对次参的模。
  11. min: 计算最小值,如 min(70,30,45,20)。
  12. max: 计算最大值。

12.5、类型函数

类型函数包含 iscolor, isnumber, isstring, iskeyword, isurl, ispixel, ispercentage, isem, isunit, isruleset,返回布尔值。

12.6、颜色定义函数

颜色定义函数包含 rgb(red, green, blue), rgba(red, green, blue, alpha), argb, hsl, hsla, hsv, hsva,具体可以参看 Less 颜色定义函数

12.7、颜色通道函数

  1. hue: 在 HSL 颜色空间中,提取颜色对象的色调通道。
  2. saturation: 在 HSL 颜色空间中,提取彩色对象的饱和通道。
  3. lightness: 在 HSL 颜色空间中,从颜色对象提取亮度通道。
  4. hsvhue: 在 HSV 色彩空间中,提取色彩对象的色调通道。
  5. hsvsaturation: 在 HSL 颜色空间中,提取彩色对象的饱和通道。
  6. hsvvalue: 在 HSL 颜色空间中,提取颜色对象的值通道。
  7. red: 提取彩色对象的红色通道。
  8. green: 提取彩色对象的绿色通道。
  9. blue: 提取彩色对象的蓝色通道。
  10. alpha: 提取颜色对象的 alpha 通道。
  11. luma: 计算颜色对象的亮度值。
  12. luminance: 在没有伽马校正的情况下计算亮度值。

12.8、颜色操作函数

  1. saturate: 改变颜色的强度或饱和度,如 saturate(color, amount)。
  2. desaturate: 降低颜色的强度或饱和度。
  3. lighten: 增加颜色的亮度,如 lighten(color, amount)。
  4. darken: 降低颜色的亮度。
  5. fadein: 增加颜色的不透明度,如 fadein(color, amount)。
  6. fadeout: 降低颜色的不透明度。
  7. fade: 设置颜色的不透明度,如 fade(color, amount)。
  8. spin: 旋转颜色的角度,如 spin(color, angle)。
  9. mix: 混合两种颜色以及不透明度,如 mix(color1, color2, weight),参数 weight 为权重。
  10. tint: 混合颜色和白色,如 tint(color, weight)。
  11. shade: 混合颜色和黑色。
  12. greyscale: 丢弃颜色的饱和度,如 greyscale(color)。
  13. contrast: 设置颜色的对比度,如 contrast(color, dark, light, amount)。

12.9、颜色混合函数

  1. multiply: 两种RGB通道颜色相乘,然后除以 255 以得到较暗的颜色作为结果。
  2. screen: 获取两种颜色中更明亮的颜色。
  3. overlay: 结合 multiply, screen 的效果生成结果,使光通道更轻,暗通道更暗。
  4. softlight: 工作方式类似于 overlay 函数,但它仅使用颜色的一部分,其中柔和地突出显示其他颜色。
  5. hardlight: 与 overlay 函数类似,但颜色的作用相反。 它使用第二个参数执行 overlay()函数,以确定是否应该执行乘法或屏幕操作。
  6. difference: 从首参颜色中减去次参颜色,负值将反转。
  7. exclusion: 类似于 difference 函数,但具有较低的对比度。
  8. average: 计算两种颜色的均值。
  9. negation: 与 difference 函数相反,从次参颜色减去首参颜色。

12.10、长度相关

  1. length:获取列表长度
  2. extract:获取列表对应索引的值

Map

从 Less 3.5 版本开始,你还可以将混合(mixins)和规则集(rulesets)作为一组值的映射(map)使用。

1
2
3
4
5
6
7
8
9
#colors() {
primary: blue;
secondary: green;
}

.button {
color: #colors[primary];
border: 1px solid #colors[secondary];
}

输出符合预期:

1
2
3
4
.button {
color: blue;
border: 1px solid green;
}

List

定义一组数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* 
.color-@{len} {
color: extract(@colorlist,2);
}
*/
@colorlist: #FFF,#FF0,#F00,#C3C,#000; /* 定义列表 */
@len: length(@colorlist); /* 5 */


.color(@count) when(@count <= @len){ /* @count 小于等于 @len才有效 */
.color(@count + 1);
.color-@{count} {
color: extract(@colorlist,@count); /* 获取list对应索引的值 */
}
}
.color(1);

其他

自定义函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* one.less */
.container(@prefix){
.@{prefix}-title{
color: #31F153;
font-size: 16px;
}
}

/* two.less */
@import "./one.less";
@prefix: login;

.container(@prefix);
<div className="container">
<h1 className="login-title">Hello CodeSandbox</h1>
</div>

img

  • 标题: less使用指南
  • 作者: 爱吃猪头爱吃肉
  • 创建于: 2023-04-27 08:54:34
  • 更新于: 2023-04-27 22:35:12
  • 链接: https://zsasjy.github.io/2023/04/27/less使用指南/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
推荐文章
前端 CSS 代码规范 前端 CSS 代码规范 webpack常用配置汇总 webpack常用配置汇总 浏览器架构 浏览器架构 搭建react开发环境 搭建react开发环境 Docker基本用法 Docker基本用法 学习算法 学习算法
 评论