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基本用法 学习算法 学习算法
 评论