Less 条件表达式、循环以及合并属性

本文介绍的是 less 中的条件表达式和循环。这两个概念和混入搭配使用可以极大的提升 less 代码的复用,提升代码的可维护性和通用性。是步入 less 高级使用不可错过的技巧!

1. 条件表达式

1.1 比较运算符

和 less 中相关的比较运算符有:> >= < <= true这几个,也就是通常能够产生布尔值的符号。

1.2 语法格式

less 中的条件表达式,一般是结合 mixin 来使用的,具体来说,其语法可以简单的理解为在 mixin 后面添加额外的代码: when () 表示对其作用范围的限制。

less 复制代码
.mixin(@a) when (lightness(@a) >= 50%) {
  background-color: @a;
}

.mixin(#ddd);

1.3 相关函数

要想 less 条件写得好,除了知道相关的运算符,还需要知道相关的函数,比如上面代码中的 lightness 函数。而之所以有这些函数,主要还是因为 css 中的属性值往往带有单位并且是复合属性。所以从字面量上很难计算,于是需要一种模式,将其中感兴趣的数据提取出来。

那么除了上面的 lightness 函数,比较常用的函数还有如下:

1.3.1 类型检测函数

  • iscolor: 检测变量是不是合法的颜色值。
  • isnumber: 检测变量是不是数字。
  • isstring: 检测变量是不是字符串。
  • iskeyword: 检测是不是关键字。
  • isurl: 检测变量是不是合法的url。
less 复制代码
// 自定义函数来模拟 iscolor  
.iscolor(@value) when (iscolor(@value)) {  
  color-test: 'true';  
}  
.iscolor(@value) when (not iscolor(@value)) {  
  color-test: 'false';  
}  
  
// 自定义函数来模拟 isnumber  
.isnumber(@value) when (isnumber(@value)) {  
  number-test: 'true';  
}  
.isnumber(@value) when (not isnumber(@value)) {  
  number-test: 'false';  
}  
  
// 自定义函数来模拟 isstring (Less中的变量通常都是字符串,这里主要是为了示例)  
.isstring(@value) when (@value = '') {  
  string-test: 'true';  
}  
.isstring(@value) when not (@value = '') {  
  string-test: 'false';  
}  
  
// Less本身没有iskeyword或isurl的内置函数,所以我们可以通过正则表达式来简单模拟  
// 这里只是示例,并没有实现完整的正则表达式匹配  
.iskeyword(@value) when (@value = 'keyword') {  
  keyword-test: 'true';  
}  
.iskeyword(@value) when not (@value = 'keyword') {  
  keyword-test: 'false';  
}  
  
.isurl(@value) when (@value = 'http://example.com') {  
  url-test: 'true';  
}  
.isurl(@value) when not (@value = 'http://example.com') {  
  url-test: 'false';  
}  
  
// 使用示例  
#test-area {  
  // 测试颜色  
  .iscolor(#ff0000); // 应该返回 'true'  
  color-test-red: @color-test;  
    
  .iscolor(notacolor); // 应该返回 'false'  
  color-test-notacolor: @color-test;  
    
  // 测试数字  
  .isnumber(123); // 应该返回 'true'  
  number-test-numeric: @number-test;  
    
  .isnumber(abc); // 应该返回 'false'  
  number-test-nonnumeric: @number-test;  
    
  // 测试字符串 (在Less中通常所有值都可以当作字符串处理)  
  .isstring('this is a string'); // 应该返回 'true',但这个示例可能不准确,因为Less处理值的方式与这个简单测试不完全相符  
  string-test-string: @string-test;  
    
  .isstring(123); // 即使传入数字,也可能返回 'true',这取决于Less如何将值解释为字符串  
  string-test-nonstring: @string-test;  
    
  // 测试关键字  
  .iskeyword(keyword); // 应该返回 'true',这里只是一个非常简单的示例  
  keyword-test-keyword: @keyword-test;  
    
  .iskeyword(notakeyword); // 应该返回 'false'  
  keyword-test-notakeyword: @keyword-test;  
    
  // 测试URL  
  .isurl('http://example.com'); // 应该返回 'true',这里只是一个示例,并没有实现完整的URL匹配逻辑  
  url-test-valid: @url-test;  
    
  .isurl('not a url'); // 应该返回 'false'  
  url-test-invalid: @url-test;  
}

1.3.2 单位检测函数

  • ispixel: 检测变量是不是合法的颜色值。
  • ispercentage: 检测变量是不是数字。
  • isem: 检测变量是不是字符串。
  • isunit: 检测是不是关键字。
less 复制代码
// 示例:使用ispercentage函数  
.test-percentage(@value) when (ispercentage(@value)) {  
  percentage-test: 'true';  
}  
.test-percentage(@value) when not (ispercentage(@value)) {  
  percentage-test: 'false';  
}  
  
#percentage-test {  
  .test-percentage(50%); // 返回 'true'  
  .test-percentage(50);  // 返回 'false'  
  percentage-result: @percentage-test;  
}  
  
// 示例:使用isunit函数  
.test-unit(@value) when (isunit(@value, px)) {  
  unit-test: 'true';  
}  
.test-unit(@value) when not (isunit(@value, px)) {  
  unit-test: 'false';  
}  
  
#unit-test {  
  .test-unit(10px); // 返回 'true'  
  .test-unit(10);   // 返回 'false'  
  unit-result: @unit-test;  
}  
  
// 示例:检测一个值是否为字符串(在Less中,大多数值都可以视为字符串)  
.test-string(@value) when (@value = '') {  
  string-test: 'true'; // 这里的判断逻辑比较简化,只是为了演示  
}  
.test-string(@value) when not (@value = '') {  
  string-test: 'false';  
}  
  
#string-test {  
  .test-string('');        // 返回 'true'  
  .test-string(not-empty);  // 返回 'false'  
  string-result: @string-test;  
}  
  
// 注意:由于Less中并没有直接的isstring函数,上述的test-string函数只是为了演示目的。  
// 在实际应用中,大多数传递给Less的值都可以被当作字符串处理。  
  
// 假设的ispixel和isem函数并不是Less的内置函数,如果需要这样的功能,需要自定义混合(mixin)来实现。

1.4 结合检测函数和混入做重载

如下所示,结合能够发挥更大的威力!

2. 循环

less 中的循环是通过让 混合 来调用自身实现的;如果结合条件表达式和自增量就可以将这种递归的调用控制在一个合理的范围内,从而实现预定目的。

如下的代码能够反映出 less 中循环的巨大威力:

less 复制代码
.posCommon(@w,@h,@t,@l,@pos:absolute) {
  position: @pos;  
  left: @l; 
  top: @t; 
  width: @w;
  height: @h;
}

.generate-content(@index:1,@params:@contentLefts) when (@index<=length(@contentLefts)) {
  @left: extract(@params,@index);
  .content@{index} {  
    .posCommon(14.90%, 25.00%, 71.57%, @left);  
    outline: 1px solid transparent;  
  }  
  .generate-content(@index+1);
}

.generate-content();

3. 合并属性

在使用 mixin 的时候难免会遇到这样的问题:

less 复制代码
.mixin(){
    box-shadow: inset 0 0 10px #555;
}

.myclass {
    .mixin();
    box-shadow: 0 0 20px black;
}

这样写,混合根本就不会有什么效果,因为 css 本质上是相互覆盖的;而上面的代码明显就是想要将两个 box-shadow 中的属性合在一起,这个时候可以使用合并属性 ,使用合并属性非常的容易,那就是在冒号之前加上 + 即可,写成:+:

less 复制代码
.mixin(){
    box-shadow+: inset 0 0 10px #555;
}

.myclass {
    .mixin();
    box-shadow+: 0 0 20px black;
}

编译之后的结果为:

less 复制代码
.myclass {
    box-shadow+: inset 0 0 10px #555, 0 0 20px black;
}

注意上面的逗号。

聪明的你一定想到了,在 css 中有两种分割方法,一个是使用空格 进行分割,而另一种方式就是上面所示的使用逗号进行分割。

下面展示如何使用空格进行分割。其实就是将 + 变成 +_即可:

那么,问题来了 ,如果我多次使用合并属性,并且每次或用 + 或用 +_ 这个时候又如何?

  • 这个时候只看最后一次合并属性用的是 + 还是 +_

示例:

less 复制代码
.button {  
  .border-radius(5px);  
  .box-shadow(0 0 10px rgba(0, 0, 0, .5));  
  padding: 10px;  
  background-color: blue;  
  color: white;  
}  
  
.button-special {  
  .button(); // 继承 .button 的样式  
  background-color: red; // 覆盖背景颜色  
  border: 2px solid green; // 添加新的边框样式  
}  
  
// 假设我们想要合并两个具有相同属性的样式规则  
.merged-styles {  
  .button-special(); // 继承 .button-special 的样式,包括 background-color 和 border  
  border: 3px dashed orange, 2px solid green; // 合并 border 属性,Less 会自动处理  
}  
  
// 生成的 CSS 将是:  
// .merged-styles {  
//   border-radius: 5px;  
//   box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);  
//   padding: 10px;  
//   color: white;  
//   background-color: red;  
//   border: 3px dashed orange, 2px solid green; // 合并后的 border 属性  
// }
相关推荐
蜗牛攻城狮6 天前
PostCSS 详解、最佳实践及其与 Less/SCSS 的关系
less·前端开发·postcss·scss
cc蒲公英12 天前
less和sass区别
前端·less·sass
小明记账簿12 天前
利用 Less 循环高效生成多组 CSS 间距工具类
前端·css·less
juma900218 天前
基于 Xilinx K7 325t 的千兆网 UDP 协议实现小记
less
小书包酱20 天前
告别在 vue 中使用公共 less 文件没有提示信息的烦恼
css·vue.js·less
abiao19811 个月前
VUE style标签中添加lang=less属性
前端·vue.js·less
IT从业者张某某1 个月前
less 工具 OpenHarmony PC适配实践
前端·microsoft·less
qq_415216251 个月前
vue3搭建项目yarn+vue3+webpack+less+element-plus
前端·webpack·less
NPE~1 个月前
[Linux命令分享]日志查看 — — less
linux·运维·less·常用命令·日志查看
泷羽Sec-静安1 个月前
Less-9 GET-Blind-Time based-Single Quotes
服务器·前端·数据库·sql·web安全·less