Less logo

Less

以低学习成本著称的 CSS 超集预处理器

CSS预处理器Less变量嵌套

Less 保持与标准 CSS 高度兼容,同时提供变量、嵌套和混入等增强能力,适合希望平滑升级现有样式代码的团队。

Less

一门向后扩展 CSS 语言的样式表语言,以简洁的 CSS 超集语法提供变量、嵌套、混入等预处理能力。

技术简介说明

Less 由 Alexis Sellier(云梯公司创始人)于 2009 年开发,是受 Sass 启发而创建的 CSS 预处理器。Less 的设计哲学是"学习成本最小化"——它的语法是标准 CSS 的严格超集,这意味着任何合法的 CSS 代码同时也是合法的 Less 代码。这种设计使得现有 CSS 代码可以零成本迁移到 Less。

Less 最初用 Ruby 编写,后来迁移至 JavaScript 实现,使其可以直接在 Node.js 环境中运行,也支持在浏览器端直接编译(不推荐用于生产环境)。Less 在前端社区中拥有重要地位,尤其在中国开发者社区中使用广泛,知名的 Ant Design UI 框架就选择了 Less 作为样式方案。

Less 的核心价值在于其低学习曲线和实用性。它不追求成为一门"编程语言"(如 Sass 或 Stylus),而是专注于提供 CSS 开发者最需要的增强能力:变量、混入(Mixin)、嵌套规则和运算。这种务实的设计使得 Less 成为团队快速上手 CSS 预处理的首选方案。

基本信息

项目说明
官网https://lesscss.org
GitHubhttps://github.com/less/less.js
LicenseApache-2.0
最新版本4.4.0(2025 年 10 月发布)
主要维护者Alexis Sellier(原始作者)、Less.js 核心团队
实现语言JavaScript
npm 周下载量约 500-800 万

快速上手

安装

# 全局安装 CLI 工具
npm install -g less
 
# 项目内安装(推荐)
npm install -D less
 
# 使用 pnpm
pnpm add -D less
 
# 验证安装
lessc --version

基础配置

独立使用 CLI

# 编译单个文件
lessc styles.less styles.css
 
# 压缩输出
lessc --compress styles.less styles.css
 
# 监听文件变化
lessc --watch styles.less styles.css
 
# 包含源映射
lessc --source-map styles.less styles.css
 
# 指定 include 路径
lessc --include-path=src/styles/ main.less output.css

Vite 集成

# Vite 内置支持 Less,只需安装 less
pnpm add -D less
// vite.config.js(可选配置)
import { defineConfig } from 'vite'
 
export default defineConfig({
  css: {
    preprocessorOptions: {
      less: {
        modifyVars: {
          '@primary-color': '#3498db',
          '@border-radius-base': '4px',
        },
        javascriptEnabled: true, // 允许在 Less 中使用 JS 表达式
      },
    },
  },
})

Webpack 集成

pnpm add -D less less-loader
// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.less$/,
        use: [
          'style-loader',
          'css-loader',
          {
            loader: 'less-loader',
            options: {
              lessOptions: {
                modifyVars: {
                  '@primary-color': '#3498db',
                },
                javascriptEnabled: true,
              },
            },
          },
        ],
      },
    ],
  },
}

最小示例

// 变量定义
@primary-color: #3498db;
@font-stack: 'Helvetica Neue', Arial, sans-serif;
@spacing: 8px;
 
// 混入(Mixin)
.border-radius(@radius: 4px) {
  border-radius: @radius;
  -webkit-border-radius: @radius;
  -moz-border-radius: @radius;
}
 
// 嵌套
.nav {
  background-color: @primary-color;
  font-family: @font-stack;
 
  &__item {
    padding: @spacing * 2;
    color: #fff;
 
    &:hover {
      color: lighten(@primary-color, 20%);
    }
 
    &--active {
      font-weight: bold;
      .border-radius(8px);
    }
  }
}
 
// 运算
.container {
  width: 100% - 20px;
  padding: @spacing * 2;
}

核心概念与架构

编译模型

Less 是 编译时预处理器,在构建阶段将 .less 文件编译为标准 CSS。它也可以配置为在浏览器端运行时编译(通过 less.js),但这种方式仅推荐用于开发阶段。

架构设计

Less 的编译流程分为三个阶段:

  1. 解析(Parsing):将 Less 源码解析为抽象语法树(AST)
  2. 求值(Evaluation):处理变量、Mixin 调用、运算等
  3. 生成(Generation):将处理后的 AST 输出为标准 CSS

变量与懒加载

Less 变量采用"延迟加载"策略,变量可以在定义之前使用。编译时,Less 会先扫描整个文件,找到所有变量定义,然后再进行替换。

// Less 中合法 —— 变量在声明之前使用
.header {
  color: @brand-primary; // 编译时能找到下面的定义
}
 
@brand-primary: #3498db;

命名空间与访问器

Less 通过嵌套的 Mixin 实现命名空间模式,用于组织和复用代码:

#bundle() {
  .button {
    padding: 10px 20px;
    border: none;
  }
  .header {
    font-size: 24px;
  }
}
 
.my-button {
  #bundle.button();
}

核心特性

1. 变量(Variables)

// 基础变量
@primary: #3498db;
@font-size-base: 14px;
@line-height-ratio: 1.5;
 
// 变量可用于任何 CSS 属性值
.button {
  background: @primary;
  font-size: @font-size-base;
  line-height: @line-height-ratio;
}
 
// 变量也可用于选择器、属性名、URL
@my-selector: .container;
@{my-selector} {
  width: 1200px;
}

2. 混入(Mixins)

// 基本混入
.clearfix() {
  &::after {
    content: '';
    display: table;
    clear: both;
  }
}
 
// 带参数的混入
.border-radius(@radius: 4px) {
  border-radius: @radius;
}
 
// 带多个参数
.size(@width; @height) {
  width: @width;
  height: @height;
}
 
// 使用
.box {
  .clearfix();
  .border-radius(8px);
  .size(200px; 100px);
}

3. 嵌套(Nesting)

// 选择器嵌套
.nav {
  display: flex;
 
  .nav-item {
    padding: 8px 16px;
 
    a {
      color: #333;
      text-decoration: none;
 
      &:hover {
        color: #3498db;
      }
    }
  }
 
  // 父选择器引用
  &-brand {
    font-weight: bold;
  }
}
 
// 媒体查询嵌套(Less 4.0+)
@media (min-width: 768px) {
  .sidebar {
    width: 250px;
 
    @media (min-width: 1200px) {
      width: 300px;
    }
  }
}

4. 运算(Operations)

// 算术运算
@base-size: 16px;
 
.container {
  width: 100% - 40px;
  padding: @base-size * 2;
  margin: @base-size / 2;
}
 
// 颜色运算
@dark: #333;
@light: @dark + #111;   // #444444
@lighter: @dark * 2;    // #666666

5. 继承(Extend)

// 基本继承
.animated {
  transition: all 0.3s ease;
}
 
.button {
  &:extend(.animated);
  padding: 8px 16px;
}
 
// all 关键字 —— 替换所有引用
.link {
  &:extend(.animated all);
}

6. 条件语句(when 守卫)

// 基于条件的 Mixin
.make-button(@style) when (@style = primary) {
  background: #3498db;
  color: white;
}
 
.make-button(@style) when (@style = secondary) {
  background: #ecf0f1;
  color: #333;
}
 
.make-button(@style) when (isnumber(@style)) and (@style > 10) {
  font-size: @style * 1px;
}
 
// 使用
.btn-a { .make-button(primary); }
.btn-b { .make-button(secondary); }
.btn-c { .make-button(16); }

7. 循环(Loop)

// 生成网格类
.generate-columns(@n, @i: 1) when (@i =< @n) {
  .col-@{i} {
    width: (100% / @n) * @i;
  }
  .generate-columns(@n, (@i + 1));
}
 
.grid {
  .generate-columns(12);
}

8. 内置函数

// 颜色函数
@base: #3498db;
@lighter: lighten(@base, 20%);
@darker: darken(@base, 20%);
@saturated: saturate(@base, 20%);
@mixed: mix(#3498db, #e74c3c, 50%);
@faded: fade(@base, 50%);
 
// 字符串函数
@upper: uppercase('hello');
@quoted: e('unquoted string');
@replaced: replace('Hello World', 'World', 'Less');
 
// 数学函数
@rounded: round(3.7);  // 4
@floored: floor(3.7);  // 3
@ceil: ceil(3.2);      // 4
@sqrt: sqrt(16);       // 4
 
// 类型检测
@is-color: iscolor(#3498db);  // true
@is-number: isnumber(16px);   // true

9. 数据 URI 内联

// 自动将图片转为 Base64 内联
.icon {
  background: data-uri('icon.svg');
}
 
// 指定 MIME 类型
.icon-png {
  background: data-uri('image/png', 'icon.png');
}

10. 导入与引用

// 导入 Less 文件
@import 'variables';       // 编译时处理
@import (reference) 'mixins'; // 仅引用变量和 Mixin,不输出 CSS
@import (inline) 'reset.css'; // 原样内联,不解析
@import (optional) 'theme';   // 文件不存在时不报错

生态图

Less 生态系统
├── 核心实现
│   ├── less.js(JavaScript 实现,官方主推)
│   └── less.rb(Ruby 实现,已废弃)
├── 构建工具集成
│   ├── Vite(内置支持)
│   ├── webpack(less-loader)
│   ├── Gulp(gulp-less)
│   ├── Parcel(内置支持)
│   ├── Grunt(grunt-contrib-less)
│   └── Turbopack(内置支持)
├── 框架集成
│   ├── Next.js(内置支持)
│   ├── Nuxt(内置支持)
│   ├── Ant Design(默认样式方案)
│   └── React/Angular/Vue 各框架兼容
├── 工具与插件
│   ├── less-plugin-clean-css(CSS 压缩)
│   ├── less-plugin-autoprefix(自动前缀)
│   ├── less-plugin-glob(通配符导入)
│   ├── less-plugin-npm-import(npm 包导入)
│   └── stylelint-less(Less 语法检查)
├── IDE 支持
│   ├── VS Code(内置语法高亮)
│   ├── WebStorm(内置支持)
│   └── Prettier(prettier-plugin-less)
└── 社区生态
    ├── Ant Design 生态(中国社区核心)
    ├── Stack Overflow(Less 标签)
    └── GitHub Discussions

适用场景

1. Ant Design 项目定制

Ant Design 使用 Less 作为样式方案,通过修改 Less 变量即可实现主题定制:

// 在项目中覆盖 Ant Design 主题变量
@import '~antd/lib/style/themes/default.less';
@primary-color: #3498db;
@border-radius-base: 4px;

2. 快速原型开发

Less 的低学习曲线使其成为快速原型开发的理想选择。开发者可以在几分钟内上手,不需要学习复杂的编程概念。

3. CSS 代码渐进增强

对于已有大量 CSS 的项目,Less 的 CSS 超集语法允许渐进式采用预处理特性,无需一次性重构。

4. 团队快速协作

新成员无需学习 Sass 或 Stylus 的独特语法,只需掌握基本的 Less 变量和嵌套即可参与开发。

5. 动态主题系统

通过 modifyVars 功能,可以在编译时动态修改 Less 变量,实现多主题方案:

// 编译时注入主题变量
less.render(source, {
  modifyVars: {
    '@primary-color': userTheme.primary,
    '@font-size-base': userTheme.fontSize,
  },
})

6. 中小型项目

对于不需要复杂逻辑的项目,Less 提供了恰到好处的预处理能力,避免过度工程化。

7. 浏览器端开发调试

Less 支持在浏览器中直接编译,可用于开发阶段的原型验证(不推荐生产使用)。

开发与工程化

目录结构推荐

src/
├── styles/
│   ├── variables.less      // 变量定义
│   ├── mixins.less          // 混入定义
│   ├── reset.less           // CSS Reset
│   ├── base.less            // 基础样式
│   ├── components/
│   │   ├── button.less
│   │   ├── input.less
│   │   └── card.less
│   ├── layouts/
│   │   ├── header.less
│   │   └── footer.less
│   ├── pages/
│   │   ├── home.less
│   │   └── about.less
│   └── main.less            // 入口文件
└── ...

主题切换方案

// themes/default.less
@primary: #3498db;
@bg: #ffffff;
@text: #333333;
 
// themes/dark.less
@primary: #5dade2;
@bg: #1a1a1a;
@text: #ffffff;
 
// themes/warm.less
@primary: #e67e22;
@bg: #fff8f0;
@text: #2c3e50;
 
// 编译时通过 modifyVars 切换主题

CI/CD 集成

# GitHub Actions 示例
- name: Install dependencies
  run: pnpm install
 
- name: Build CSS
  run: pnpm lessc --compress src/styles/main.less dist/styles/main.css
 
- name: Lint Less
  run: pnpm stylelint "src/**/*.less" --custom-syntax postcss-less

代码质量

  • Stylelint:使用 postcss-less 语法解析器进行 Less 代码检查
  • Less Plugin Clean CSS:集成 CSS 压缩
  • Prettier:配置 Less 格式化插件

性能与安全

性能特点

  • 编译速度:Less 是纯 JavaScript 实现,在 Node.js 环境中编译速度较快
  • 浏览器端编译:支持在浏览器中直接编译,但性能较差,仅用于开发
  • 增量编译:构建工具配合实现增量编译,提升开发效率
  • 生产优化--compress 选项输出压缩 CSS

性能建议

  • 避免深层嵌套(建议不超过 3 层)
  • 合理使用 @import (reference) 避免输出无用 CSS
  • 大型项目考虑合并 Less 文件,减少编译次数
  • 生产环境使用 less-plugin-clean-css 进行压缩

安全注意事项

  • javascriptEnabled 选项:允许在 Less 中使用 JavaScript 表达式,存在安全风险,谨慎启用
  • 避免将用户输入拼接到 Less 变量中
  • 审查第三方 Less 包来源

技术对比

特性LessSass/SCSSStylus
语法CSS 超集SCSS(CSS 超集)/ 缩进语法灵活(可选括号/花括号)
变量符号@var$varvar$var
学习曲线低(最易上手)中等中等
Mixin 语法.mixin()@mixin + @include函数或 Mixin
继承:extend()@extend@extends
条件语句when 守卫@if/@elseif/else/unless
循环递归 Mixin@for/@each/@whilefor/each/while
命名空间#namespace.mixin()模块系统无原生命名空间
内置函数颜色/字符串/数学颜色/字符串/列表/映射非常丰富
模块化无原生模块@use/@forward无原生模块
浏览器端支持不支持不支持
框架偏好Ant DesignBootstrapVue(历史)
社区规模大(中国社区活跃)最大中等
维护状态活跃(4.4.0)活跃(1.89.2,2.0 开发中)维护减缓

最佳实践

1. 变量命名规范

// ✅ 语义化命名
@color-primary: #3498db;
@color-text-base: #333333;
@spacing-base: 8px;
@font-size-base: 14px;
 
// ❌ 避免非语义命名
@blue: #3498db;
@color1: #333333;
@size: 8px;

2. Mixin 参数默认值

// ✅ 总是提供合理默认值
.button(@padding: 8px 16px; @radius: 4px; @bg: @primary) {
  padding: @padding;
  border-radius: @radius;
  background: @bg;
}
 
// 使用
.btn { .button(); }                  // 使用所有默认值
.btn-large { .button(12px 24px); }   // 只覆盖第一个参数

3. 合理使用 @import (reference)

// ✅ 只引用变量和 Mixin,不输出 CSS
@import (reference) 'variables';
@import (reference) 'mixins';
 
// 当前文件的样式正常输出
.card {
  .border-radius(8px); // 来自 mixins
  background: @card-bg; // 来自 variables
}

4. 避免过度使用 @extend

// ⚠️ @extend 会导致选择器合并,可能产生意外结果
// 优先使用 Mixin 实现复用
 
// ✅ 推荐
.button-base() {
  padding: 8px 16px;
  border: none;
}
 
.btn-primary {
  .button-base();
  background: blue;
}

5. 配合构建工具使用 modifyVars

// 在 Next.js 中使用 Ant Design 主题定制
// next.config.js
const withLess = require('next-with-less');
 
module.exports = withLess({
  lessLoaderOptions: {
    lessOptions: {
      modifyVars: {
        '@primary-color': '#3498db',
      },
    },
  },
});

技术局限与边界

已知限制

  1. 无原生模块系统:Less 没有类似 Sass @use/@forward 的模块化方案,依赖文件作用域和命名约定
  2. 循环语法复杂:Less 的循环通过递归 Mixin 实现,不如 Sass 的 @for/@each 直观
  3. 条件语句受限when 守卫功能有限,不支持复杂的逻辑组合
  4. 无命名空间隔离:所有变量和 Mixin 默认全局可见,大型项目可能产生命名冲突
  5. 浏览器端性能:浏览器端编译性能差,不适合生产环境

不适用场景

  • 需要高级编程能力(复杂条件、循环、函数) → 考虑 Sass
  • 需要灵活的语法(缩进风格) → 考虑 Stylus
  • 需要 CSS 未来特性 polyfill → 考虑 PostCSS + postcss-preset-env
  • 追求极致编译速度 → 考虑 Lightning CSS
  • 组件化 UI 项目 → 考虑 Tailwind CSS 或 CSS Modules

迁移注意事项

  • Less → Sass:语法差异较小,主要变更是变量符号(@$)、Mixin 语法(.mixin()@mixin + @include
  • CSS → Less:几乎零成本迁移,任何合法 CSS 都是合法 Less
  • Less 版本升级:从 3.x 升级到 4.x 注意 Math 运算语法变化(strictMath 默认行为)

学习资源

官方资源

教程

社区资源

2026 年现状

版本状态

  • 稳定版:Less 4.4.0(2025 年 10 月),持续维护更新
  • 开发版:暂无重大版本计划公布

发展趋势

  • 稳定维护期:Less 进入稳定维护阶段,不再有激进的语法更新,专注于 bug 修复和兼容性
  • Ant Design 生态依赖:Ant Design 5.x 开始转向 CSS-in-JS(@ant-design/cssinjs),但仍有大量项目使用 Less 版本
  • 社区增长平稳:npm 周下载量保持在 500-800 万,增长平稳但无大幅增长
  • 中国社区活跃:Less 在中国开发者社区中使用广泛,相关中文资源丰富

社区活跃度

  • npm 周下载量约 500-800 万,排名 CSS 预处理器第二
  • GitHub 约 17k stars
  • 主要由社区维护,无大型公司背书
  • 中国前端社区是 Less 的主要使用群体之一

未来路线图

  • 稳定性优先:Less 团队专注于维护现有功能的稳定性
  • 兼容 CSS 新特性:持续跟进 CSS 新语法,确保 CSS 超集兼容性
  • 工具链现代化:改进与 Vite、webpack 5 等现代构建工具的集成体验
  • 生态保持:只要 Ant Design Less 版本仍在维护,Less 就有稳定的使用基础