最近发现很多同学在使用 Less 的时候, 仅是为了使用 Less 的 变量、嵌套 以及 module 功能。
虽然 Less 相对于 Sass 来说,移除了很多功能,比如 @if @else @while @for @function等,但是并非是Less 不行,Less 的宗旨是 “Do Less Get More”。
我们可以在简洁的API 支撑下,做到更多的事情。
曾经我是个 Scss 党,现在已经全面转 Less 了。
导入导出
提到导入导出,大家可能都在想,一个 @import 就搞定的事情,这也拿来讲?
在Less 初期,确实都是 @import 导入文件一把梭,但是这同样也会带来代码冗余的问题,比如生成重复代码等。
Less v1.4 版本后,编译器新增了 import 参数的支持,如
静默导入
在导入的文件前,添加下划线前缀即可静默引入,即不生成实体代码,仅作为变量使用。
1 | // color filename:color.less |
refrence
1 | @import (refrence) 'color' |
refrence 可以配合 extend/mixins 关键字使用,如
1 | // color.less |
这样就只继承 color.less 的 .a ,同时在编译后的文件中,不会生成 .b 的 less 代码。
inline
如果某些css 不想被编译,且还需要引入的话,可以使用这个参数
1 | @import (inline) 'color.css' |
这样在编译项目的时候, color.css 不会经由 Less 编译器编译,这个设计的目的是防止某些编译器不支持的高级css 属性导致编译报错。
其他的参数还有:
- once(默认)
- multiple
- less
- css
有兴趣的可以自行查阅文档。
变量
普通的变量定义和引用,每种语言都一样,大家神会即可,说点 Less 不一样的。
属性变量
将变量作为 key 来使用,使用 @{} 来插值
1 | @color: red; |
变量拼接
变量作为 value 使用的时候,需要用~和引号来进行插值计算,如果不加 ~ ,则会生成字符串类型的值。
1 | .a (@p, @u) { |
路径变量
在导入文件时,同样可以使用变量,来达到按需导入的效果。
1 | // 两个主题文件 |
变量引用
同属性变量,既然变量可以作为 style 的属性,那也能作为变量的引用来用,从而就可以实现 PHP 中 $$$$a
这样的套娃用法
看我套娃~
1 | @a: 'i am origin a'; |
变量提升
同 JavaScript,Less 中的变量, 也是会提升的
1 | a { |
混入
基础用法
混入 (Mixins) 可以说是 Sass 和 Less 中一个比较常见的功能,在 Less 中基础用法比较简单:
1 | .a { |
less: 人家都说我清纯不做作, 不像外面那个 sass。
Sass 中将这个功能细分为 @mixin 、@include、@extend、@content,有兴趣的可以去研究一下。
毕竟大多数项目是不需要优化到如此地步的,即便需要优化, 也可以通过嵌套规则来优化。
函数混入
Mixins 可以作为函数使用,从而实现类似 @functions 的功能
1 | .a(@color: red) { |
如果作为函数使用,则自身不会被编译到css 文件中。
高级函数混入
Less 实现了一些高级语言才有的函数特性,如 JavaScript 中的 arguments、解构参数; Python 中的 **kwargs;
1 | .a (...) { |
- @arguments 可接收到所有的参数集
- @rest 可接收到 … 定义的参数集
高级函数重载
这里其实和强类型语言中的重载不太一样,不过为了方便理解,可以认为就是模拟重载。
1 | .a (@p1, @p2) { |
可以看到如同函数重载一般,当签名不同的时候,返回不同的结果。
混入作用域
默认的 Mixins 是可以继承调用方上下文的,即可以使用 & 来继承父级,针对比较复杂的场景,Less 提供了 #(命名空间) 加上 > 来控制作用域。
1 | #first { |
通过上面的例子可以看到, 我们可以通过命名空间 + > 来控制使用哪个同名混入。
关于 # 命名空间,后面有讲。
函数返回值
Less 并没有 Sass 中的 @return 关键字,但是因为作用域的共享,可以通过变量来实现 @return 的用法。
1 | .a() { |
可以看到,@color 变量在经过 .b 的调用后,已经可以在 .b 作用域内使用。
Mixin 条件
虽然 Less 没有提供 @if @else 等流程控制符,但是提供了 when
关键字, 配合 mixin 重载,灵活使用可以实现类似流程控制的效果。
1 | .a (@p) when (@p < 10) { |
Mixin 合并(v1.7.0 支持)
Less 支持 Mixin 的合并选项
1 | .a { |
为避免任何非有意的添加,merge
需要在每个待加入的声明中显示的设置一个+
或者+_
标记。 (引自官方文档:https://www.html.cn/doc/less/features/#merge-feature-comma-)
循环
递归循环
Less 可以通过 when 和 递归 mixin 来实现 Sass 中 @while 循环的效果
1 | .a (@i: 1) when (@i < 11){ |
列表循环
Less 中通过变量可以定义一个列表,如:
1 | @strings: left, right, top, bottom; |
此时可以通过 each
函数来循环这个列表(each 方法文档中没有,我也忘记咋知道这个方法的了~ - -~)
1 | each(@strings, .(@type) { |
嚯!到这里终于来点有用的场景了,这个写法很 JavaScript 。
函数
上面讲过我们用 Mixin 去模拟自定义函数,Less 自身也提供了很多常见的操作函数。
颜色函数
通过这些函数可以进行色彩计算、转换。
hsl() / hsla()
通过色相 (hue),饱和度 (saturation),亮度 (lightness),alpha 四种值 (HSLA) 创建不透明的颜色对象。
Hsv() / hsva()
通过色相 (hue),饱和度 (saturation),色调 (value),以及 alpha 四种值 (HSVA) 创建透明的颜色对象。
hue
saturation
lightness
red
green
blue
alpha
lighten
darken
fadein
fadeout
mix
混色,将两个颜色混成一个。
等等
类型函数
在混入的时候,可以通过类型函数来判断输出结果
- isnumber
- isstring
- iscolor
- isurl
- Isunit 是否为单位(px/em/rem)
- ispercentage
- ispixel
- isem
等等
数学函数
写动画效果、图形计算的时候非常有用,不列举了。常见的JavaScript Math 对象方法都在里面。
工具函数
某些场景贼好用
data-uri
将一个资源转为 base64 格式
data-uri(‘../data/image.jpg’);
输出:url(‘data:image/jpeg;base64,bm90IGFjdHVhbGx5IGEganBlZyBmaWxlCg==’);
util
添加或移除一个单位,在配合变量使用的时候效果极佳
Util(5, px)
输出 5px
等等
JavaScript in Less
Less 支持一个很神奇的特性,可能跟底层是 JavaScript 实现有关。
它支持我们在 Less 中编写 JavaScript,仅限 ES5,不过即便如此, 还是可以通过这个特性来大大扩展 Less 的灵活性。
从这刻起,Less 就是一门完整的编程语言了。
ant design 中就是使用这种方法来计算 Button 色阶
开启编译支持
javascript in less 需要 less loader 额外开启,默认是关闭的~
1 | // webpack |
JavaScript 编写
1 | .funtionFactory { |
Less 中调用 JavaScript 方法
1 | // 先调用工厂函数,生成作用域内的方法 |
注意:
less 中调用 JavaScript 方法的时候,是可以传递参数的。
所以我们平常也可以把 Less 中一些复杂的计算转移到 JavaScript 中去。
业务场景
需求
在日常开发中,搭建底层样式库的时候,为了方便 UI 绘制,我决定要创建一些辅助间距class,类似 Material UI 中的 pl
、ml
。
但是 Material 显然是通过 React 来计算的,那我们使用 Less 要怎么做呢?
结合一下上面的各种用法,很轻松就得出了答案:变量、循环、JavaScript。
来看一下如何实现~
实现:
1 | // 定义使用到的边距 |
这段代码编译后,就会生成四个边的边距 style,如直接在项目中使用 pl8、pr16、mb24 即可。