Skip to content

Less

简介

Less(Leaner Style Sheets)是一门CSS预处理语言,它扩展了CSS语言,增加了变量、混合(Mixins)、函数等特性,使CSS更易维护和扩展。Less可以运行在Node.js环境或浏览器环境中。

核心特性

变量

Less允许我们定义变量,使得样式值可以在多处重用:

less
// 定义变量
@primary-color: #3498db;
@secondary-color: #2ecc71;
@base-font-size: 16px;
@base-line-height: 1.5;

// 使用变量
.header {
  background-color: @primary-color;
  color: white;
  font-size: @base-font-size;
  line-height: @base-line-height;
}

.button {
  background-color: @secondary-color;
  border: 1px solid darken(@secondary-color, 10%);
  font-size: @base-font-size;
}

嵌套

Less允许CSS选择器以嵌套的方式编写,这样可以更好地反映HTML的结构:

less
.navigation {
  background-color: #f8f8f8;
  padding: 10px;
  
  // 嵌套选择器
  ul {
    list-style: none;
    margin: 0;
    padding: 0;
    
    li {
      display: inline-block;
      margin-right: 10px;
      
      a {
        color: @primary-color;
        text-decoration: none;
        
        &:hover {
          text-decoration: underline;
        }
      }
    }
  }
  
  // &符号引用父选择器
  &.transparent {
    background-color: transparent;
  }
}

混合(Mixins)

混合允许将一组属性从一个规则集包含(或混入)到另一个规则集中:

less
// 定义一个简单的混合
.bordered {
  border: 1px solid #ddd;
  border-radius: 4px;
}

// 带参数的混合
.border-radius(@radius) {
  border-radius: @radius;
  -webkit-border-radius: @radius;
  -moz-border-radius: @radius;
}

// 带默认参数的混合
.box-shadow(@x: 0, @y: 0, @blur: 1px, @color: #000) {
  box-shadow: @arguments;
  -webkit-box-shadow: @arguments;
  -moz-box-shadow: @arguments;
}

// 使用混合
.box {
  .bordered;
  .border-radius(4px);
  .box-shadow(2px, 2px, 5px, rgba(0, 0, 0, 0.3));
  padding: 20px;
}

.button {
  .border-radius(2px);
  .box-shadow(0, 1px, 3px, rgba(0, 0, 0, 0.2));
  background-color: @primary-color;
  color: white;
}

运算

Less支持算术运算,可以对数值和颜色进行加减乘除操作:

less
@base-margin: 10px;
@base-padding: 15px;
@base-font-size: 16px;

.container {
  margin: @base-margin * 2;
  padding: @base-padding + 5px;
}

.title {
  font-size: @base-font-size * 1.5;
  margin-bottom: @base-margin / 2;
}

// 颜色运算
@base-color: #111;
@light-color: #888 + #111; // 结果为 #999
@dark-color: #888 - #333;  // 结果为 #555

函数

Less内置了多种函数用于转换颜色、处理字符串和进行数学计算:

less
// 颜色函数
@base-color: #3498db;
@darker-color: darken(@base-color, 10%);  // 使颜色变暗
@lighter-color: lighten(@base-color, 10%); // 使颜色变亮
@desaturated-color: desaturate(@base-color, 20%); // 降低饱和度
@alpha-color: fade(@base-color, 50%); // 设置透明度

.element {
  color: @base-color;
  background-color: @lighter-color;
  border-color: @darker-color;
  box-shadow: 0 0 5px @alpha-color;
}

// 数学函数
@value: 5.5;
.element {
  width: round(@value) * 10px; // 四舍五入为6,然后乘以10px
  height: ceil(@value) * 10px;  // 向上取整为6,然后乘以10px
  margin: floor(@value) * 10px; // 向下取整为5,然后乘以10px
}

命名空间和访问符

可以将混合组织在命名空间中,然后使用>访问符引用它们:

less
#my-utility-library {
  .button(@color) {
    background-color: @color;
    border: 1px solid darken(@color, 10%);
    border-radius: 4px;
    padding: 5px 15px;
    
    &:hover {
      background-color: lighten(@color, 10%);
    }
  }
  
  .input(@border-color) {
    border: 1px solid @border-color;
    padding: 8px;
    border-radius: 4px;
    
    &:focus {
      border-color: darken(@border-color, 20%);
      outline: none;
    }
  }
}

// 使用命名空间中的混合
.primary-button {
  #my-utility-library > .button(@primary-color);
}

.form-input {
  #my-utility-library > .input(#ccc);
}

导入

Less允许导入其他Less文件,这有助于模块化你的样式:

less
// 导入变量文件
@import "variables.less";

// 导入混合文件
@import "mixins/buttons.less";
@import "mixins/forms.less";

// 使用导入的变量和混合
.container {
  max-width: @container-width;
  margin: 0 auto;
  .clearfix();
}

条件语句与循环

条件混合(Guard表达式)

Less支持在混合中使用条件表达式:

less
// 根据参数值应用不同样式的混合
.text-style(@size) when (@size <= 14px) {
  font-size: @size;
  color: #333;
}

.text-style(@size) when (@size > 14px) and (@size <= 20px) {
  font-size: @size;
  color: #222;
  font-weight: bold;
}

.text-style(@size) when (@size > 20px) {
  font-size: @size;
  color: #111;
  font-weight: bold;
  line-height: 1.2;
}

// 使用条件混合
.small-text {
  .text-style(12px);
}

.medium-text {
  .text-style(16px);
}

.large-text {
  .text-style(24px);
}

循环结构

Less没有显式的循环语句,但可以通过递归混合模拟循环:

less
// 创建网格系统的递归混合
.generate-columns(@n, @i: 1) when (@i =< @n) {
  .col-@{i} {
    width: (@i * 100% / @n);
  }
  .generate-columns(@n, (@i + 1));
}

// 生成12列网格系统
.generate-columns(12);

// 输出CSS将包含.col-1到.col-12的类,每个类有相应的宽度百分比

工具与集成

命令行编译

使用Less命令行工具编译Less文件:

bash
# 安装Less全局命令行工具
npm install -g less

# 编译单个文件
lessc styles.less styles.css

# 压缩输出
lessc --compress styles.less styles.min.css

# 生成源映射
lessc --source-map styles.less styles.css

与构建工具集成

Webpack

javascript
// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.less$/,
        use: [
          'style-loader',
          'css-loader',
          'less-loader'
        ]
      }
    ]
  }
};

Gulp

javascript
// gulpfile.js
const gulp = require('gulp');
const less = require('gulp-less');
const autoprefixer = require('gulp-autoprefixer');
const cleanCSS = require('gulp-clean-css');

gulp.task('less', function() {
  return gulp.src('./src/styles/**/*.less')
    .pipe(less())
    .pipe(autoprefixer())
    .pipe(cleanCSS())
    .pipe(gulp.dest('./dist/css'));
});

最佳实践

文件组织

styles/
├── main.less             # 主入口文件
├── variables.less        # 变量定义
├── mixins/               # 混合目录
│   ├── buttons.less      # 按钮相关混合
│   ├── forms.less        # 表单相关混合
│   └── layout.less       # 布局相关混合
├── components/           # 组件样式
│   ├── header.less       # 头部组件
│   ├── footer.less       # 底部组件
│   ├── navigation.less   # 导航组件
│   └── forms.less        # 表单组件
├── pages/                # 页面特定样式
│   ├── home.less         # 首页样式
│   ├── about.less        # 关于页样式
│   └── contact.less      # 联系页样式
└── vendors/              # 第三方库样式覆盖
    ├── bootstrap.less    # Bootstrap覆盖
    └── jquery-ui.less    # jQuery UI覆盖

命名约定

  • 使用连字符分隔的小写名称(kebab-case)命名类和ID
  • 变量名应该描述其用途而不是值
  • 使用有意义的前缀组织变量(如@color-@font-@spacing-
less
// 好的命名
@color-primary: #3498db;
@color-secondary: #2ecc71;
@font-size-base: 16px;
@spacing-unit: 8px;

// 避免这样命名
@blue: #3498db;
@green: #2ecc71;
@size: 16px;
@space: 8px;

性能考虑

  • 避免过度嵌套(不超过3-4层)
  • 合理组织和复用混合
  • 使用&符号减少重复选择器

与Sass的对比

特性LessSass
语法CSS扩展语法有两种语法:SCSS(类CSS)和缩进语法
变量@变量名$变量名
作用域有作用域,但有变量提升严格的作用域规则
混合.mixin()@mixin和@include
嵌套规则支持支持
继承通过混合实现通过@extend实现
条件语句Guard表达式@if, @else
循环递归混合@for, @each, @while
导入@import@import, @use (Sass新版)
函数内置函数和自定义函数内置函数和@function
命名空间支持通过模块支持
运行环境浏览器和Node.js只能预编译

常见问题与解决方案

变量作用域问题

less
// 问题:变量覆盖
@color: red;

.section {
  @color: blue;
  // 在这里,@color是blue
  background: @color;
  
  .subsection {
    // 在这里,@color仍然是blue
    color: @color;
  }
}

// 解决方案:使用局部变量
.section {
  @local-color: blue;
  background: @local-color;
  
  .subsection {
    color: @local-color;
  }
}

混合与继承选择

less
// 使用混合(会复制所有属性)
.common-styles() {
  border: 1px solid #ddd;
  padding: 10px;
  border-radius: 4px;
}

.box-1 {
  .common-styles();
  background: #f9f9f9;
}

.box-2 {
  .common-styles();
  background: #eaeaea;
}

// 更高效的方法:使用扩展
.common-styles {
  border: 1px solid #ddd;
  padding: 10px;
  border-radius: 4px;
}

.box-1:extend(.common-styles) {
  background: #f9f9f9;
}

.box-2:extend(.common-styles) {
  background: #eaeaea;
}

学习资源