【LESS系列】高级特性
前面我已经有一篇文章是写 LESS 的基础语法的。
那么这一次我们来看一下 LESS 的高级特性。
说起高级特性,首先也必须要一提的是模式匹配。
虽然个人觉得模式匹配的实用度其实也是一般般,但在关键时候,有它们在的话,还是能够让我们开发得更得心应手的。
其实传参设置默认值,就是一个最简单的模式匹配。
你调用 Mixins 函数,传入参数,和不传入参数,可能会出现不同的编译结果。
OK了,还是上主菜吧,下面列出了几项 LESS 的高级特性。
按照先前的惯例,LESS CODE 和 CSS CODE 分别是编译前跟编译后的代码。
1.用不同参数个数来匹配不同的 Mixins
/* LESS CODE */ .test(@size){ width: @size; } .test(@size, @multiple){ width: @size * @multiple; } .el-a{ .test(10px); } .el-b{ .test(10px, 2); }
/* CSS CODE */ .el-a { width: 10px; } .el-b { width: 20px; }
2.用常量参数来匹配不同的 Mixins
/* LESS CODE */ .test(large, @size: 10px){ width: @size * 2; } .test(simple, @size: 10px){ width: @size; } .test(@_, @size: 10px){ display: block; } .el-a{ .test(large); } .el-b{ .test(simple); }
/* CSS CODE */ .el-a { width: 20px; display: block; } .el-b { width: 10px; display: block; }
以下是整个过程如何发生的:
第一个 .test 只有在满足 large 条件才会被匹配;
第二个 .test 只有在满足 simple 条件才会被匹配;
第三个 .test 在任何条件下,甚至是 large 和 simple 以外的条件下都会被匹配,只要满足传参规则就可以了(.test 要求传入1~2个参数);
只要是满足匹配要求的 Mixins,都会被使用。
变量可以匹配任何值,而常量只有在传入的值与之完全相等时才可以匹配成功。
3.用条件表达式来控制模式匹配
/* LESS CODE */ .test(@size) when (@size >= 10){ width: @size; color: #f00; } .test(@size) when (@size < 10){ width: @size; color: #000; } .el-a{ .test(20px); } .el-b{ .test(5px); }
/* CSS CODE */ .el-a { width: 20px; color: #f00; } .el-b { width: 5px; color: #000; }
有了条件表达式,总算可以跟 SASS 的 @if 比拼一下了,虽然实际用起来感觉还是不如 @if,但总比被完爆要强不少了。
4.条件表达式中使用类型检测函数
/* LESS CODE */ .test(@param) when (iscolor(@param)){ color: @param; } .test(@param) when (isnumber(@param)){ width: @param; } .el-a{ .test(#f00); } .el-b{ .test(5px); }
/* CSS CODE */ .el-a { color: #ff0000; } .el-b { width: 5px; }
当然,上面的例子仅仅是列出了两个类型检测函数,LESS 提供了很多类型检测函数,如:iscolor、isnumber、isstring、iskeyword、isurl等等,具体的话,我会在下一篇 LESS 函数说明中提及。
5.条件表达式中使用 and、or、not
/* LESS CODE */ .test(@size) when (@size > 10) and (@size < 20){ width: @size; color: #000; } .test(@size) when (@size < 10), (@size > 20){ width: @size; color: #ff0; } .test(@size) when not (@size = 20){ text-align: center; } .el-a{ .test(15px); } .el-b{ .test(5px); } .el-c{ .test(10px); }
/* CSS CODE */ .el-a { width: 15px; color: #000; text-align: center; } .el-b { width: 5px; color: #ff0; text-align: center; } .el-c { text-align: center; }
细心的同学会发现,LESS 中的逻辑与,是用英文逗号“,”来实现的,而不是直接用 or。
6.条件表达式中参数和参数进行比较
/* LESS CODE */ .test(@width, @height) when (@width >= @height){ width: @width; height: @height; background-color: #000; } .test(@width, @height) when (@width < @height){ width: @width; height: @height; background-color: #f00; } .el-a{ .test(10px, 20px); } .el-b{ .test(20px, 10px); }
/* CSS CODE */ .el-a { width: 10px; height: 20px; background-color: #f00; } .el-b { width: 20px; height: 10px; background-color: #000; }
7.高级参数用法
/* LESS CODE */ /* 不接受任何参数 */ .test(){ ... } /* 接受任意多个参数 */ .test(...){ ... } /* 接受1个参数 */ .test(@size: 1px){ ... } /* 接受0~1个参数 */ .test(@size){ ... } /* 同样是接受任意多个参数 */ .test(@size: 1px, ...){ ... } /* 接受1~N个参数 */ .test(@size, ...){ ... }
主要是说明“...”的用法,另外还有先前(在基本语法一文中)提到的 @arguments 变量,如果已经淡忘,那可以去回顾下了。
8.作用域
/* LESS CODE */ .test(@bgColor, @size){ .set-bg-color(){ background: @bgColor; } .set-size(){ width: @size; height: @size; } .set-bg-color(); .set-size(); } .el-a{ .test(#fff, 20px); }
/* CSS CODE */ .el-a { background: #ffffff; width: 20px; height: 20px; }
可以看到,在 .test 中,我还定义了两个 Mixins (就是 .set-bg-color 和 .set-size),但是这两个 Mixins 的作用域仅仅是在 .test 之中,如果在外部调用是会编译报错的。
而 .set-bg-color 和 .set-size 作为 .test 的内部 Mixins,它们本身虽然没参数,却又可以直接使用 .test 的参数。
是不是和 JS 很像?如果你对 JS 的作用域有所了解,那么这些应该不难理解。
9.字符串插值
/* LESS CODE */ .test(@domain){ background-image: url("@{domain}/img/test.png"); } .el-a{ .test('http://asset.img.com'); }
/* CSS CODE */ .el-a { background-image: url("http://asset.img.com/img/test.png"); }
这一个特性在统一配置静态资源所在域中会有很好的发挥
10.避免编译
/* LESS CODE */ .test(){ filter: ~"ms:alwaysHasItsOwnSyntax.For.Stuff()"; } .el-a{ .test(); }
/* CSS CODE */ .el-a { filter: ms:alwaysHasItsOwnSyntax.For.Stuff(); }
对于像滤镜这种特别的 CSS (特别之处在于这样的 CSS 本身就是一种函数调用,而 LESS 又没有提供这样的函数),LESS 通过 ~"内容" 这样格式来直接输出内容,避免对内容部分进行编译。
11.在 LESS 中使用 Javascript
/* LESS CODE */ .el-a{ font-size: 12px; color: #f00; &:before{ @arr: 'hello', 'world'; content: `@{arr}.join(' ').toUpperCase()`; } }
/* CSS CODE */ .el-a { font-size: 12px; color: #f00; } .el-a:before { content: "HELLO WORLD"; }
上面的例子中,可以捕抓到几个点:
如何用 LESS 变量来定义数组,@arr: 'hello', 'world';
如何在 LESS 中使用 JS(用“``”来包住要执行的JS语句),and 当中的 JS 如何获取 LESS 中定义的变量(用“@{变量名}”的格式),content: `@{arr}.join(' ').toUpperCase()`;
由于一般情况下,我们都是用 LESS 编译出 CSS 后,直接引用 CSS 文件的。所以在 LESS 中一般都不会使用和 DOM 相关的 JS 代码;
虽然说,能在 LESS 中使用 JS 是一件很让人兴奋的事,但实际上...除了极少时候需要做字符串处理外,真的想不到有什么时候需要用到这一特性...