高级特性与模式
LESS高级特性与模式
本文将介绍LESS的高级特性和常用设计模式,帮助你更有效地组织和管理样式代码。
动态规则集
LESS支持分离规则集,可以将规则集赋值给变量:
@detached-ruleset: {
background-color: red;
.nested {
color: white;
}
};
.component {
@detached-ruleset();
}
参数化规则集
动态规则集可以接受参数,实现更灵活的样式复用:
@detached-ruleset: {@color: blue; @margin: 20px; {
background-color: @color;
margin: @margin;
.nested {
color: lighten(@color, 20%);
}
}};
.component-1 {
@detached-ruleset();
}
.component-2 {
@detached-ruleset({@color: green; @margin: 10px;});
}
规则集作用域
规则集可以访问其定义环境和调用环境的变量:
@var: global;
.mixin() {
@var: mixin;
// 定义规则集
@rules: {
// 这里可以访问 mixin 作用域
@var-in-rules: @var; // 值为 "mixin"
value: @var; // 值为 "mixin"
};
// 返回规则集
@return: @rules;
}
.caller {
@var: caller;
// 调用混合并获取规则集
@result: .mixin();
// 应用规则集
@result();
// 这里输出 "mixin",而不是 "caller" 或 "global"
}
规则集合并
多个规则集可以合并使用:
@base: {
color: red;
font-size: 14px;
};
@extra: {
background-color: #f5f5f5;
padding: 10px;
};
.component {
@base();
@extra();
border: 1px solid #ddd;
}
混合守卫
LESS支持在混合中使用条件表达式,称为"守卫"(Guards):
.mixin(@a) when (@a > 10) {
background-color: black;
}
.mixin(@a) when (@a <= 10) {
background-color: white;
}
.class-1 {
.mixin(15); // 背景色为黑色
}
.class-2 {
.mixin(5); // 背景色为白色
}
复合守卫
可以使用逻辑运算符组合多个条件:
.mixin(@a) when (@a > 10) and (@a < 20) {
background-color: blue;
}
.mixin(@a) when (@a <= 10), (@a >= 20) {
background-color: green;
}
.class-1 {
.mixin(15); // 背景色为蓝色
}
.class-2 {
.mixin(5); // 背景色为绿色
}
.class-3 {
.mixin(25); // 背景色为绿色
}
类型检查守卫
可以检查参数的类型:
.mixin(@a) when (isnumber(@a)) {
width: @a;
}
.mixin(@a) when (iscolor(@a)) {
background-color: @a;
}
.mixin(@a) when (isstring(@a)) {
content: @a;
}
.class-1 {
.mixin(15px); // 设置宽度
}
.class-2 {
.mixin(#ff0000); // 设置背景色
}
.class-3 {
.mixin("hello"); // 设置内容
}
默认混合
使用default()
函数创建默认混合:
.mixin(@a) when (default()) {
color: black;
}
.mixin(@a) when not (default()) and (@a > 10) {
color: white;
}
.class-1 {
.mixin(15); // 颜色为白色
}
.class-2 {
.mixin(5); // 颜色为黑色
}
递归混合
LESS支持递归混合,可以用来生成重复的样式:
.generate-columns(@n, @i: 1) when (@i =< @n) {
.col-@{i} {
width: (@i * 100% / @n);
}
.generate-columns(@n, (@i + 1));
}
// 生成12列网格系统
.generate-columns(12);
递归生成间距类
@spacer: 8px;
@spacers: 0, 1, 2, 3, 4, 5;
.generate-spacers(@list, @i: 1) when (@i <= length(@list)) {
@value: extract(@list, @i);
@space: @value * @spacer;
.m-@{value} { margin: @space; }
.mt-@{value} { margin-top: @space; }
.mr-@{value} { margin-right: @space; }
.mb-@{value} { margin-bottom: @space; }
.ml-@{value} { margin-left: @space; }
.p-@{value} { padding: @space; }
.pt-@{value} { padding-top: @space; }
.pr-@{value} { padding-right: @space; }
.pb-@{value} { padding-bottom: @space; }
.pl-@{value} { padding-left: @space; }
.generate-spacers(@list, @i + 1);
}
.generate-spacers(@spacers);
递归生成颜色变体
@colors: {
primary: #007bff;
success: #28a745;
danger: #dc3545;
warning: #ffc107;
info: #17a2b8;
};
.generate-color-variants(@i: 1) when (@i <= length(@colors)) {
@pair: extract(extract(@colors, @i), 1);
@name: extract(@pair, 1);
@color: extract(@pair, 2);
.text-@{name} {
color: @color;
}
.bg-@{name} {
background-color: @color;
color: contrast(@color, black, white);
}
.border-@{name} {
border-color: @color;
}
.generate-color-variants(@i + 1);
}
.generate-color-variants();
命名空间
LESS允许使用命名空间组织混合:
#my-library {
.button() {
display: inline-block;
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
}
.primary-button() {
.button();
background-color: #007bff;
color: white;
}
.secondary-button() {
.button();
background-color: #6c757d;
color: white;
}
}
// 使用命名空间中的混合
.btn-primary {
#my-library.primary-button();
}
.btn-secondary {
#my-library.secondary-button();
}
命名空间导入
可以导入命名空间并使用别名:
// buttons.less
#buttons {
.base() {
display: inline-block;
padding: 6px 12px;
border-radius: 4px;
}
.primary() {
.base();
background-color: #007bff;
color: white;
}
}
// main.less
@import "buttons.less";
// 使用导入的命名空间
.btn {
#buttons.base();
}
.btn-primary {
#buttons.primary();
}
命名空间嵌套
命名空间可以嵌套:
#theme {
#buttons {
.primary() {
background-color: #007bff;
color: white;
}
}
#forms {
.input() {
border: 1px solid #ced4da;
padding: 6px 12px;
}
}
}
.button {
#theme#buttons.primary();
}
.input {
#theme#forms.input();
}
映射
LESS 3.5+支持映射数据结构:
@breakpoints: {
xs: 0;
sm: 576px;
md: 768px;
lg: 992px;
xl: 1200px;
};
.responsive-container {
width: 100%;
@media (min-width: @breakpoints[sm]) {
max-width: 540px;
}
@media (min-width: @breakpoints[md]) {
max-width: 720px;
}
@media (min-width: @breakpoints[lg]) {
max-width: 960px;
}
@media (min-width: @breakpoints[xl]) {
max-width: 1140px;
}
}
映射操作
可以动态访问和操作映射:
@theme: {
primary: #007bff;
secondary: #6c757d;
success: #28a745;
danger: #dc3545;
};
// 访问映射值
.button-primary {
background-color: @theme[primary];
border-color: darken(@theme[primary], 10%);
}
// 遍历映射
.generate-buttons(@map, @i: 1) when (@i <= length(@map)) {
@pair: extract(extract(@map, @i), 1);
@name: extract(@pair, 1);
@color: extract(@pair, 2);
.btn-@{name} {
background-color: @color;
border-color: darken(@color, 10%);
color: contrast(@color, black, white);
}
.generate-buttons(@map, @i + 1);
}
.generate-buttons(@theme);
嵌套映射
映射可以嵌套:
@config: {
colors: {
primary: #007bff;
secondary: #6c757d;
};
fonts: {
base: 'Helvetica, Arial, sans-serif';
heading: 'Georgia, serif';
};
sizes: {
small: 12px;
medium: 16px;
large: 20px;
};
};
body {
font-family: @config[fonts][base];
font-size: @config[sizes][medium];
color: @config[colors][secondary];
}
h1, h2, h3 {
font-family: @config[fonts][heading];
color: @config[colors][primary];
}
插件系统
LESS支持插件,可以扩展其功能:
// 使用插件
@plugin "my-plugin";
// 调用插件函数
.element {
color: my-plugin-function(#007bff);
}
常用插件
一些常用的LESS插件:
// less-plugin-autoprefix
@plugin "autoprefix";
.element {
display: flex;
// 自动添加浏览器前缀
}
// less-plugin-clean-css
// 用于压缩CSS输出
// less-plugin-functions
@plugin "functions";
.element {
// 使用扩展函数
width: add(100px, 20px);
}
高级模式与最佳实践
组件模式
将样式组织为独立组件:
// button.less
.button {
display: inline-block;
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
&-primary {
background-color: #007bff;
color: white;
&:hover {
background-color: darken(#007bff, 10%);
}
}
&-secondary {
background-color: #6c757d;
color: white;
&:hover {
background-color: darken(#6c757d, 10%);
}
}
&-sm {
padding: 4px 8px;
font-size: 12px;
}
&-lg {
padding: 8px 16px;
font-size: 18px;
}
}
主题系统
创建可切换的主题:
// themes.less
.theme-light() {
--bg-color: #ffffff;
--text-color: #333333;
--border-color: #dddddd;
--primary-color: #007bff;
}
.theme-dark() {
--bg-color: #222222;
--text-color: #f5f5f5;
--border-color: #444444;
--primary-color: #0d6efd;
}
// 应用主题
body {
&.light {
.theme-light();
}
&.dark {
.theme-dark();
}
}
// 使用主题变量
.card {
background-color: var(--bg-color);
color: var(--text-color);
border: 1px solid var(--border-color);
}
.button {
background-color: var(--primary-color);
color: white;
}
配置驱动样式
使用配置对象驱动样式生成:
// config.less
@config: {
grid-columns: 12;
grid-gutter: 30px;
breakpoints: {
xs: 0;
sm: 576px;
md: 768px;
lg: 992px;
xl: 1200px;
};
colors: {
primary: #007bff;
secondary: #6c757d;
success: #28a745;
danger: #dc3545;
warning: #ffc107;
info: #17a2b8;
};
spacing: {
base: 8px;
small: 4px;
large: 16px;
};
};
// 使用配置生成网格系统
.generate-grid(@config) {
.container {
width: 100%;
padding-right: @config[grid-gutter] / 2;
padding-left: @config[grid-gutter] / 2;
margin-right: auto;
margin-left: auto;
@media (min-width: @config[breakpoints][sm]) {
max-width: 540px;
}
@media (min-width: @config[breakpoints][md]) {
max-width: 720px;
}
@media (min-width: @config[breakpoints][lg]) {
max-width: 960px;
}
@media (min-width: @config[breakpoints][xl]) {
max-width: 1140px;
}
}
.row {
display: flex;
flex-wrap: wrap;
margin-right: -(@config[grid-gutter] / 2);
margin-left: -(@config[grid-gutter] / 2);
}
.col {
position: relative;
width: 100%;
padding-right: @config[grid-gutter] / 2;
padding-left: @config[grid-gutter] / 2;
}
.generate-columns(@i: 1) when (@i <= @config[grid-columns]) {
.col-@{i} {
flex: 0 0 percentage(@i / @config[grid-columns]);
max-width: percentage(@i / @config[grid-columns]);
}
.generate-columns(@i + 1);
}
.generate-columns();
}
// 应用配置
.generate-grid(@config);
模块化组织
使用模块化方式组织LESS代码:
// 文件结构
// styles/
// ├── variables.less
// ├── mixins.less
// ├── reset.less
// ├── components/
// │ ├── buttons.less
// │ ├── forms.less
// │ └── cards.less
// ├── layouts/
// │ ├── grid.less
// │ ├── header.less
// │ └── footer.less
// └── main.less
// main.less
@import "variables.less";
@import "mixins.less";
@import "reset.less";
// 组件
@import "components/buttons.less";
@import "components/forms.less";
@import "components/cards.less";
// 布局
@import "layouts/grid.less";
@import "layouts/header.less";
@import "layouts/footer.less";
// 按需导入
@import (optional) "themes/custom-theme.less";
条件编译
使用条件编译生成不同环境的样式:
// 定义环境变量
@env: "production"; // 或 "development"
// 根据环境变量条件编译
.debug() when (@env = "development") {
.debug-info {
display: block;
border: 1px solid red;
padding: 10px;
margin: 10px 0;
background-color: #ffeeee;
}
}
.debug() when (@env = "production") {
.debug-info {
display: none;
}
}
// 应用条件编译
.debug();
// 压缩选项
.optimize() when (@env = "production") {
// 生产环境下移除注释和空白
// 通常通过命令行参数实现
}
.optimize();
高级技巧
动态导入
根据条件动态导入文件:
@theme: "dark";
// 动态导入主题文件
@import "@{theme}-theme.less";
// 条件导入
.import-rtl() when (@rtl = true) {
@import "rtl.less";
}
@rtl: false;
.import-rtl();
属性合并
LESS支持属性合并,用于处理多值属性:
// 使用逗号合并
.mixin() {
box-shadow+: 0 1px 3px rgba(0, 0, 0, 0.12);
}
.box {
.mixin();
box-shadow+: 0 1px 2px rgba(0, 0, 0, 0.24);
// 编译为: box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
}
// 使用空格合并
.mixin() {
transform+_: scale(1.2);
}
.element {
.mixin();
transform+_: rotate(30deg);
// 编译为: transform: scale(1.2) rotate(30deg);
}
父选择器引用
高级父选择器引用技巧:
.component {
&-header {
// 编译为 .component-header
font-weight: bold;
}
&__title {
// 编译为 .component__title (BEM风格)
font-size: 18px;
}
&--large {
// 编译为 .component--large (BEM风格)
padding: 20px;
}
.theme-dark & {
// 编译为 .theme-dark .component
background-color: #333;
}
body.rtl & {
// 编译为 body.rtl .component
direction: rtl;
}
@media (max-width: 768px) {
&-header {
// 编译为 @media (max-width: 768px) { .component-header { ... } }
font-size: 16px;
}
}
}
延迟加载
LESS支持变量的延迟加载:
// 变量的延迟加载
@var: 0;
.class {
@var: 1;
one: @var; // 输出 1
@var: 2;
two: @var; // 输出 2
}
// 混合的延迟加载
.mixin(@a: 0) {
value: @a;
.inner {
value-inner: @a;
}
}
.class {
.mixin(1); // 传入 1
// 重新定义混合
.mixin(@a: 0) {
// 新的实现
value-redefined: @a;
}
.other {
.mixin(2); // 使用新定义的混合
}
}
作用域提升
LESS中的变量可以在使用前定义:
.class {
@color: blue; // 在使用前定义
.nested {
color: @color; // 使用上面定义的变量
}
// 重新定义变量
@color: green;
background-color: @color; // 使用重新定义的变量,输出 green
}
性能优化
选择器优化
优化LESS选择器以提高性能:
// 不推荐 - 过深的嵌套
.header {
.navigation {
ul {
li {
a {
color: blue;
}
}
}
}
}
// 推荐 - 扁平化选择器
.header-nav-link {
color: blue;
}
// 使用父选择器引用减少重复
.nav-item {
display: inline-block;
&-link {
color: blue;
&:hover {
text-decoration: underline;
}
}
}
混合优化
优化混合使用以减少CSS输出大小:
// 不推荐 - 每次使用都会复制所有CSS
.box-shadow() {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
-moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
}
// 推荐 - 使用继承减少重复
.box-shadow {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
-moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
}
.card {
&:extend(.box-shadow);
padding: 10px;
}
.modal {
&:extend(.box-shadow);
background-color: white;
}
变量缓存
缓存复杂计算结果以提高性能:
// 不推荐 - 重复计算
.element-1 {
width: (100% / 3);
}
.element-2 {
margin-left: (100% / 3);
}
// 推荐 - 缓存计算结果
@one-third: (100% / 3);
.element-1 {
width: @one-third;
}
.element-2 {
margin-left: @one-third;
}
调试技巧
输出调试信息
使用注释输出调试信息:
@debug: true;
.debug(@message) when (@debug = true) {
/* DEBUG: @{message} */
}
// 使用调试函数
@width: percentage(1/3);
.debug("计算宽度: @{width}");
.element {
width: @width;
}
检查变量
检查变量值和类型:
@value: 15px;
.check-value() {
/*
Value: @{value}
Type:
isNumber: @{isnumber(@value)}
isPixel: @{ispixel(@value)}
isPercentage: @{ispercentage(@value)}
isColor: @{iscolor(@value)}
isString: @{isstring(@value)}
*/
}
.check-value();
使用Source Maps
在编译时启用Source Maps以便于调试:
lessc styles.less styles.css --source-map
与其他工具集成
与PostCSS集成
LESS可以与PostCSS结合使用:
// 编译流程:LESS -> CSS -> PostCSS处理
// 使用Autoprefixer等PostCSS插件处理LESS编译后的CSS
// 在构建工具中配置
// 例如webpack配置:
// {
// test: /\.less$/,
// use: [
// 'style-loader',
// 'css-loader',
// 'postcss-loader', // 应用PostCSS处理
// 'less-loader'
// ]
// }
与CSS模块集成
LESS可以与CSS模块结合使用:
// 在webpack中配置CSS模块
// {
// test: /\.less$/,
// use: [
// 'style-loader',
// {
// loader: 'css-loader',
// options: {
// modules: true,
// localIdentName: '[name]__[local]--[hash:base64:5]'
// }
// },
// 'less-loader'
// ]
// }
// 在组件中使用
// import styles from './styles.less';
// <div className={styles.container}>...</div>
实际应用案例
响应式框架
使用LESS创建响应式框架:
// 定义断点
@breakpoints: {
xs: 0;
sm: 576px;
md: 768px;
lg: 992px;
xl: 1200px;
};
// 媒体查询混合
.media-up(@breakpoint, @content) {
@min-width: @breakpoints[@breakpoint];
@media (min-width: @min-width) {
@content();
}
}
.media-down(@breakpoint, @content) {
@max-width: @breakpoints[@breakpoint];
@media (max-width: @max-width - 1) {
@content();
}
}
// 响应式容器
.container {
width: 100%;
padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto;
.media-up(sm, {
max-width: 540px;
});
.media-up(md, {
max-width: 720px;
});
.media-up(lg, {
max-width: 960px;
});
.media-up(xl, {
max-width: 1140px;
});
}
// 响应式栅格
.row {
display: flex;
flex-wrap: wrap;
margin-right: -15px;
margin-left: -15px;
}
.col {
position: relative;
width: 100%;
padding-right: 15px;
padding-left: 15px;
}
// 生成响应式列
.make-col(@size, @columns: 12) {
flex: 0 0 percentage(@size / @columns);
max-width: percentage(@size / @columns);
}
// 生成响应式类
.generate-grid-columns(@columns: 12) {
.loop-columns(@i) when (@i <= @columns) {
.col-@{i} {
.make-col(@i, @columns);
}
.loop-columns(@i + 1);
}
.loop-columns(1);
// 为每个断点生成列
.loop-breakpoints(@breakpoint-name) {
@breakpoint: extract(@breakpoints, @breakpoint-name);
.media-up(@breakpoint-name, {
.loop-columns(@i) when (@i <= @columns) {
.col-@{breakpoint-name}-@{i} {
.make-col(@i, @columns);
}
.loop-columns(@i + 1);
}.loop-columns(1);
});
}
// 遍历所有断点
.loop-breakpoints(sm);
.loop-breakpoints(md);
.loop-breakpoints(lg);
.loop-breakpoints(xl);
}
// 生成网格系统
.generate-grid-columns();
组件库开发
使用LESS创建可复用的组件库:
// 定义组件变量
@component-prefix: "ui";
@primary-color: #007bff;
@border-radius: 4px;
@animation-duration: 0.3s;
// 创建按钮组件
.@{component-prefix}-button {
display: inline-block;
padding: 8px 16px;
border-radius: @border-radius;
font-size: 14px;
line-height: 1.5;
text-align: center;
cursor: pointer;
transition: all @animation-duration;
// 变体
&--primary {
background-color: @primary-color;
color: white;
border: 1px solid darken(@primary-color, 10%);
&:hover {
background-color: darken(@primary-color, 10%);
}
}
&--outline {
background-color: transparent;
color: @primary-color;
border: 1px solid @primary-color;
&:hover {
background-color: fade(@primary-color, 10%);
}
}
// 尺寸
&--small {
padding: 4px 8px;
font-size: 12px;
}
&--large {
padding: 12px 20px;
font-size: 16px;
}
// 状态
&--disabled {
opacity: 0.65;
pointer-events: none;
}
}
// 创建卡片组件
.@{component-prefix}-card {
border-radius: @border-radius;
border: 1px solid #ddd;
background-color: white;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
overflow: hidden;
&__header {
padding: 16px;
border-bottom: 1px solid #ddd;
font-weight: bold;
}
&__body {
padding: 16px;
}
&__footer {
padding: 16px;
border-top: 1px solid #ddd;
background-color: #f8f9fa;
}
}
动画系统
使用LESS创建可复用的动画系统:
// 定义动画变量
@animation-duration: 0.3s;
@animation-timing: ease-in-out;
// 创建动画混合
.transition(@property: all, @duration: @animation-duration, @timing: @animation-timing, @delay: 0s) {
transition: @property @duration @timing @delay;
}
.keyframes(@name, @rules) {
@-webkit-keyframes @name { @rules(); }
@keyframes @name { @rules(); }
}
// 定义常用动画
.keyframes(fade-in, {
from { opacity: 0; }
to { opacity: 1; }
});
.keyframes(slide-up, {
from { transform: translateY(20px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
});
.keyframes(pulse, {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
});
// 应用动画
.animate(@name, @duration: @animation-duration, @timing: @animation-timing, @delay: 0s, @iteration: 1, @direction: normal, @fill-mode: both) {
animation-name: @name;
animation-duration: @duration;
animation-timing-function: @timing;
animation-delay: @delay;
animation-iteration-count: @iteration;
animation-direction: @direction;
animation-fill-mode: @fill-mode;
}
// 使用动画
.fade-in {
.animate(fade-in);
}
.slide-up {
.animate(slide-up);
}
.pulse {
.animate(pulse, 1s, ease-in-out, 0s, infinite);
}
高级实战案例
响应式仪表板
使用LESS创建响应式仪表板布局:
// 仪表板变量
@dashboard-bg: #f5f7fa;
@widget-bg: white;
@widget-border: #e5e9f2;
@widget-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
@header-height: 60px;
@sidebar-width: 240px;
@sidebar-collapsed-width: 64px;
// 仪表板布局
.dashboard {
display: flex;
min-height: 100vh;
background-color: @dashboard-bg;
// 侧边栏
&__sidebar {
width: @sidebar-width;
background-color: #2c3e50;
color: white;
transition: width 0.3s;
&--collapsed {
width: @sidebar-collapsed-width;
.dashboard__nav-text {
display: none;
}
}
}
// 主内容区
&__main {
flex: 1;
display: flex;
flex-direction: column;
}
// 顶部导航
&__header {
height: @header-height;
background-color: white;
border-bottom: 1px solid @widget-border;
display: flex;
align-items: center;
padding: 0 20px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
}
// 内容区
&__content {
flex: 1;
padding: 20px;
overflow-y: auto;
}
// 小部件网格
&__grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
grid-gap: 20px;
@media (max-width: 768px) {
grid-template-columns: 1fr;
}
}
// 小部件
&__widget {
background-color: @widget-bg;
border-radius: 4px;
border: 1px solid @widget-border;
box-shadow: @widget-shadow;
overflow: hidden;
&-header {
padding: 15px;
border-bottom: 1px solid @widget-border;
font-weight: 500;
display: flex;
justify-content: space-between;
align-items: center;
}
&-body {
padding: 15px;
}
&--full {
grid-column: 1 / -1;
}
&--half {
@media (min-width: 992px) {
grid-column: span 2;
}
}
}
}
主题切换系统
使用LESS创建动态主题切换系统:
// 主题配置
@themes: {
light: {
bg-color: #ffffff;
text-color: #333333;
primary-color: #007bff;
secondary-color: #6c757d;
border-color: #dee2e6;
shadow-color: rgba(0, 0, 0, 0.1);
};
dark: {
bg-color: #1a1a1a;
text-color: #f8f9fa;
primary-color: #0d6efd;
secondary-color: #6c757d;
border-color: #444444;
shadow-color: rgba(0, 0, 0, 0.3);
};
blue: {
bg-color: #f0f8ff;
text-color: #333333;
primary-color: #0056b3;
secondary-color: #6c757d;
border-color: #b8daff;
shadow-color: rgba(0, 86, 179, 0.1);
};
};
// 生成主题CSS变量
.generate-theme-vars(@theme-name, @theme) {
body[data-theme="@{theme-name}"] {
@pairs: extract(@theme, 1);
.loop-pairs(@i: 1) when (@i <= length(@pairs)) {
@pair: extract(@pairs, @i);
@key: extract(@pair, 1);
@value: extract(@pair, 2);
--@{key}: @value;
.loop-pairs(@i + 1);
}
.loop-pairs();
}
}
// 遍历所有主题
.loop-themes(@i: 1) when (@i <= length(@themes)) {
@theme-pair: extract(@themes, @i);
@theme-name: extract(@theme-pair, 1);
@theme-values: extract(@theme-pair, 2);
.generate-theme-vars(@theme-name, @theme-values);
.loop-themes(@i + 1);
}
.loop-themes();
// 使用主题变量的组件
.themed-component {
background-color: var(--bg-color);
color: var(--text-color);
border: 1px solid var(--border-color);
box-shadow: 0 2px 4px var(--shadow-color);
&__header {
background-color: var(--primary-color);
color: white;
}
&__button {
background-color: var(--secondary-color);
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
&:hover {
background-color: darken(var(--secondary-color), 10%);
}
}
}
// 主题切换器
.theme-switcher {
display: flex;
gap: 10px;
&__option {
width: 24px;
height: 24px;
border-radius: 50%;
cursor: pointer;
border: 2px solid transparent;
&--active {
border-color: var(--primary-color);
}
&--light {
background-color: #ffffff;
box-shadow: 0 0 0 1px #dee2e6;
}
&--dark {
background-color: #1a1a1a;
}
&--blue {
background-color: #f0f8ff;
box-shadow: 0 0 0 1px #b8daff;
}
}
}
总结
LESS的高级特性和模式为CSS开发提供了强大的工具,使样式代码更加模块化、可维护和可扩展。本文介绍了以下关键概念:
- 动态规则集:将样式规则封装为变量,实现更灵活的样式复用
- 混合守卫:使用条件表达式控制混合的应用
- 递归混合:通过递归生成重复样式,如网格系统和间距类
- 命名空间:组织和管理混合,避免命名冲突
- 映射:使用键值对存储和访问配置数据
- 插件系统:扩展LESS的功能
- 高级模式:组件模式、主题系统、配置驱动样式等
- 性能优化:选择器优化、混合优化、变量缓存等
- 调试技巧:输出调试信息、检查变量、使用Source Maps
- 与其他工具集成:PostCSS、CSS模块等
通过掌握这些高级特性和模式,开发者可以构建更加强大、灵活和可维护的样式系统,提高CSS开发效率和代码质量。