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;
}
}
}
}
这个混合做了以下工作:
- 使用
extract()函数从值中提取颜色、下划线标记和简单标记 - 使用条件判断(
when)生成不同的类:- 如果是'simple'类,只生成颜色样式
- 非'simple'类会额外添加指针光标和可选的下划线效果
- 使用插值(
@{name})动态生成类名 - 为每个类生成一个
-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%);
}
}
}
这个混合的功能:
- 提取三种颜色值
- 生成基础按钮样式
- 添加悬停和聚焦状态:
- 悬停时使用
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. 技术亮点总结
- 映射(Maps)的使用:将相关样式配置组织在一起,提高可维护性
- each()循环:减少重复代码,实现DRY原则
- 条件判断(when) :根据参数生成不同的样式变体
- 颜色函数(lighten/darken) :自动生成交互状态的颜色变化
- 插值语法:动态生成类名
- 嵌套规则:简化hover/focus等伪类的编写
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;
}
*/
使用说明:
-
将上述代码保存为.less文件
-
在项目中引入该文件
-
直接在HTML中使用生成的类名,如:
<span class="red">红色文字</span><button class="btn-blue">蓝色按钮</button>
-
如需添加新颜色,只需在对应的@fontColors或@btnColors映射中添加新条目即可 注释掉的CSS示例部分在实际使用中不需要包含,这里只是为了展示最终会生成什么样的CSS代码。