Less高阶用法:动态生成样式类的艺术

197 阅读6分钟

Less高阶用法:动态生成样式类的艺术

在CSS预处理器中,Less提供了强大的编程能力,让我们可以更高效地编写样式代码。本文将深入探讨如何利用Less的循环、条件判断和混合功能来动态生成字体颜色类和按钮颜色类。

1. 动态生成字体颜色类

1.1 基础结构

less

@fontColors: {
  red: #F56C6C;
  orangered: #faad3a 'underline';
  yellow: #FFFF00;
  green: #67c23a;
  blue: #2196f3 'underline';
  darkBlue: #00008B;
  grey: #adabab '' 'simple';
};

这里我们定义了一个名为@fontColors的映射(Maps),其中:

  • 键(key)是颜色名称
  • 值(value)可以是一个颜色值,也可以是一个包含多个值的列表

1.2 循环处理

less

each(@fontColors, {
  .generateFontColorClass(@key, @value);
});

使用each()函数遍历@fontColors映射,对每一项调用.generateFontColorClass混合。

1.3 生成字体颜色类的混合

less

.generateFontColorClass(@name, @value) {
  @colorValue: extract(@value, 1);
  @isUnderlined: extract(@value, 2);
  @isSimple: extract(@value, 3);
  
  .@{name} when (@isSimple = 'simple') {
    color: @colorValue !important;
  }
  
  .@{name} when not(@isSimple = 'simple'){
    color: @colorValue !important;
    cursor: pointer;
    &-nopointer {
      color: @colorValue !important;
    }
    & when (@isUnderlined = 'underline') {
      &:hover {
        text-decoration: underline;
      }
    }
  }
}

这个混合做了以下工作:

  1. 使用extract()函数从值中提取颜色、下划线标记和简单标记
  2. 使用条件判断(when)生成不同的类:
    • 如果是'simple'类,只生成颜色样式
    • 非'simple'类会额外添加指针光标和可选的下划线效果
  3. 使用插值(@{name})动态生成类名
  4. 为每个类生成一个-nopointer变体

1.4 生成结果示例

css

.red {
  color: #F56C6C !important;
  cursor: pointer;
}
.red-nopointer {
  color: #F56C6C !important;
}

.orangered {
  color: #faad3a !important;
  cursor: pointer;
}
.orangered-nopointer {
  color: #faad3a !important;
}
.orangered:hover {
  text-decoration: underline;
}

.grey {
  color: #adabab !important;
}

2. 动态生成按钮颜色类

2.1 基础结构

less

@btnColors: {
/* 色值按顺序依次为 背景颜色 字体颜色 边框颜色 */
  btn-gray: #7a83ad #fff #7a83ad;
  btn-green: #67c23a #fff #67c23a;
  btn-blue: #2fa5e5 #fff #2fa5e5;
  btn-darkBlue: #1b52d6 #fff #1b52d6;
  btn-red: #e3517c #fff #e3517c;
  btn-purple: #bd51e3 #fff #bd51e3;
  btn-yellow: #ec8d62 #fff #ec8d62;
  btn-primarys: #5d7fde #fff #5d7fde;
  btn-orange: #ebb563 #fff #ebb563;
  btn-white: #fff #3e54bc #3e54bc;
  btn-default: #fff #5b6371 #dfe5ea;
};

定义了一个@btnColors映射,每个值包含三个颜色值:背景色、文字色和边框色。

2.2 循环处理

less

each(@btnColors, {
  .generateBtnColorClass(@key, @value);
});

同样使用each()函数遍历映射并调用生成混合。

2.3 生成按钮颜色类的混合

less

.generateBtnColorClass(@name, @value) {
  @colorValue: extract(@value, 1);
  @fontColorValue: extract(@value, 2);
  @borderColorValue: extract(@value, 3);
  
  .@{name} {
    color: @fontColorValue;
    background-color: @colorValue;
    border-color: @borderColorValue;
    
    &:hover {
      color: @fontColorValue;
      background: lighten(@colorValue,10%);
      border-color: lighten(@borderColorValue,10%);
    }
    
    &:focus {
      color: @fontColorValue;
      background: darken(@colorValue, 5%);
      border-color: darken(@borderColorValue,5%);
    }
  }
}

这个混合的功能:

  1. 提取三种颜色值
  2. 生成基础按钮样式
  3. 添加悬停和聚焦状态:
    • 悬停时使用lighten()函数使颜色变亮10%
    • 聚焦时使用darken()函数使颜色变暗5%

2.4 生成结果示例

css

.btn-gray {
  color: #fff;
  background-color: #7a83ad;
  border-color: #7a83ad;
}
.btn-gray:hover {
  color: #fff;
  background: #8f97c0;
  border-color: #8f97c0;
}
.btn-gray:focus {
  color: #fff;
  background: #6e77a0;
  border-color: #6e77a0;
}

.btn-white {
  color: #3e54bc;
  background-color: #fff;
  border-color: #3e54bc;
}
.btn-white:hover {
  color: #3e54bc;
  background: #fff;
  border-color: #4f65d0;
}
.btn-white:focus {
  color: #3e54bc;
  background: #f2f2f2;
  border-color: #2d43aa;
}

3. 技术亮点总结

  1. 映射(Maps)的使用:将相关样式配置组织在一起,提高可维护性
  2. each()循环:减少重复代码,实现DRY原则
  3. 条件判断(when) :根据参数生成不同的样式变体
  4. 颜色函数(lighten/darken) :自动生成交互状态的颜色变化
  5. 插值语法:动态生成类名
  6. 嵌套规则:简化hover/focus等伪类的编写

4. 实际应用建议

  1. 扩展性:可以轻松添加新的颜色变体,只需在映射中添加新条目
  2. 维护性:所有样式配置集中管理,修改方便
  3. 一致性:确保相同类型的元素有统一的交互效果
  4. 性能:生成的CSS是静态的,没有运行时开销

这种高阶Less用法特别适合需要维护大量样式变体的项目,如设计系统或组件库。通过参数化的方式生成样式,既能保证一致性,又能提高开发效率。

5. 以下是完整的Less代码

/* ====================== */
/* 动态生成字体颜色类 */
/* ====================== */
@fontColors: {
  red: #F56C6C;
  orangered: #faad3a 'underline';
  yellow: #FFFF00;
  green: #67c23a;
  blue: #2196f3 'underline';
  darkBlue: #00008B;
  grey: #adabab '' 'simple';
};

each(@fontColors, {
  .generateFontColorClass(@key, @value);
});

.generateFontColorClass(@name, @value) {
  @colorValue: extract(@value, 1);
  @isUnderlined: extract(@value, 2);
  @isSimple: extract(@value, 3);
  
  .@{name} when (@isSimple = 'simple') {
    color: @colorValue !important;
  }
  
  .@{name} when not(@isSimple = 'simple'){
    color: @colorValue !important;
    cursor: pointer;
    &-nopointer {
      color: @colorValue !important;
    }
    & when (@isUnderlined = 'underline') {
      &:hover {
        text-decoration: underline;
      }
    }
  }
}

/* ====================== */
/* 动态生成按钮颜色类 */
/* ====================== */
@btnColors: {
  /* 色值按顺序依次为 背景颜色 字体颜色 边框颜色 */
  btn-gray: #7a83ad #fff #7a83ad;
  btn-green: #67c23a #fff #67c23a;
  btn-blue: #2fa5e5 #fff #2fa5e5;
  btn-darkBlue: #1b52d6 #fff #1b52d6;
  btn-red: #e3517c #fff #e3517c;
  btn-purple: #bd51e3 #fff #bd51e3;
  btn-yellow: #ec8d62 #fff #ec8d62;
  btn-primarys: #5d7fde #fff #5d7fde;
  btn-orange: #ebb563 #fff #ebb563;
  btn-white: #fff #3e54bc #3e54bc;
  btn-default: #fff #5b6371 #dfe5ea;
};

each(@btnColors, {
  .generateBtnColorClass(@key, @value);
});

.generateBtnColorClass(@name, @value) {
  @colorValue: extract(@value, 1);
  @fontColorValue: extract(@value, 2);
  @borderColorValue: extract(@value, 3);
  
  .@{name} {
    color: @fontColorValue;
    background-color: @colorValue;
    border-color: @borderColorValue;
    
    &:hover {
      color: @fontColorValue;
      background: lighten(@colorValue,10%);
      border-color: lighten(@borderColorValue,10%);
    }
    
    &:focus {
      color: @fontColorValue;
      background: darken(@colorValue, 5%);
      border-color: darken(@borderColorValue,5%);
    }
  }
}

/* ====================== */
/* 生成的CSS示例(实际不需要这部分,仅为展示) */
/* ====================== */
/*
.red {
  color: #F56C6C !important;
  cursor: pointer;
}
.red-nopointer {
  color: #F56C6C !important;
}

.orangered {
  color: #faad3a !important;
  cursor: pointer;
}
.orangered-nopointer {
  color: #faad3a !important;
}
.orangered:hover {
  text-decoration: underline;
}

.grey {
  color: #adabab !important;
}

.btn-gray {
  color: #fff;
  background-color: #7a83ad;
  border-color: #7a83ad;
}
.btn-gray:hover {
  color: #fff;
  background: #8f97c0;
  border-color: #8f97c0;
}
.btn-gray:focus {
  color: #fff;
  background: #6e77a0;
  border-color: #6e77a0;
}

.btn-white {
  color: #3e54bc;
  background-color: #fff;
  border-color: #3e54bc;
}
.btn-white:hover {
  color: #3e54bc;
  background: #fff;
  border-color: #4f65d0;
}
.btn-white:focus {
  color: #3e54bc;
  background: #f2f2f2;
  border-color: #2d43aa;
}
*/

使用说明:

  1. 将上述代码保存为.less文件

  2. 在项目中引入该文件

  3. 直接在HTML中使用生成的类名,如:

    • <span class="red">红色文字</span>
    • <button class="btn-blue">蓝色按钮</button>
  4. 如需添加新颜色,只需在对应的@fontColors或@btnColors映射中添加新条目即可 注释掉的CSS示例部分在实际使用中不需要包含,这里只是为了展示最终会生成什么样的CSS代码。