Less CSS 预处理:动态样式表语言

FreeGuideOnline 最新 2026-06-15

Less CSS 预处理:动态样式表语言

Less 是一门 CSS 预处理语言,它在 CSS 的语法基础之上,引入了变量、混合、运算、函数等动态特性,让样式表的编写更加高效、可维护。通过 Less 编译器,最终生成的依然是标准的 CSS 文件,因此浏览器无需任何特殊支持即可正常解析。

与原生 CSS 相比,Less 就像是为样式赋予了编程思维。你可以在一个地方定义颜色、字体,然后在任意位置复用它们;可以通过嵌套直观地反映 HTML 层级结构;还可以封装一组样式并在不同选择器中按需调用。这些能力大幅减少了代码冗余,让修改和扩展都变得更加安全、快捷。

快速上手:从安装到编译

Less 的编译可以在多种环境下执行,你无需掌握复杂的构建工具即可立即开始使用。

在浏览器端体验(开发阶段)

最简单的方式是通过 JS 直接在浏览器中解析 Less 文件。在 HTML 中引入 .less 文件,并在其之前加载 Less.js。

<link rel="stylesheet/less" type="text/css" href="styles.less" />
<script src="https://cdn.jsdelivr.net/npm/less" ></script>

注意: 这种方式不适合生产环境,每次页面加载都会实时编译,影响性能。建议仅在本地快速试验时使用。

命令行工具(推荐)

通过 Node.js 的 npm 全局安装 Less 编译器,之后可以在终端中将 .less 文件编译为 .css

npm install -g less
lessc styles.less styles.css

lessc 命令支持多种选项,例如压缩输出:

lessc --clean-css styles.less styles.min.css

与构建工具集成

实际项目通常配合 Webpack、Gulp、Vite 等工具使用。以 Webpack 为例,配置 less-loader 后,每次保存文件即可自动编译。Vue 单文件组件中,直接在 <style lang="less"> 内编写 Less,由 vue-loader 自动处理。

变量:一次定义,全局复用

变量是 Less 最基础也最强大的特性。你可以把颜色、字体系列、尺寸值等定义为变量,在任意地方引用。一旦需要修改主题色,只需更改变量的值,所有引用处都会同步生效。

// 定义变量
@primary-color: #3b82f6;
@border-radius: 8px;
@base-font: 'Helvetica Neue', sans-serif;

// 使用变量
.button {
  background-color: @primary-color;
  border-radius: @border-radius;
  font-family: @base-font;
}

变量插值:变量还可以用在选择器名称、属性名、URL 中,使用 @{} 包裹。

@selector: banner;
@image-path: "../images";

.@{selector} {
  background: url("@{image-path}/bg.png");
}

作用域与延迟加载:Less 变量遵循块级作用域,但表现类似“延迟加载”——在同一个作用域内,变量可以预先使用,后面才定义,最终取值以最后定义的为准。这一特性让变量可被覆盖,十分灵活。

@color: red;
.box {
  color: @color;   // 最后会是 blue
  @color: blue;
}

混合:封装可复用的样式块

混合(Mixin)让你把一组样式规则当作函数一样,在其他规则集中“调用”。混合可以携带参数,具备默认值,甚至支持内容条件判断。

无参数混合

定义一个普通的类选择器,当它在另一个规则集中被引用时,它的所有属性都会被复制过来。

// 定义混合
.rounded-corners {
  border-radius: 6px;
  -webkit-border-radius: 6px;
}

// 使用混合
.card {
  .rounded-corners();
  background: #fff;
}

如果混合不希望输出到 CSS(作为纯粹的工具类),可以在其名称后加上 (),这样编译时不会生成对应的选择器。

.clearfix() {
  &:after {
    content: "";
    display: table;
    clear: both;
  }
}
.container {
  .clearfix();
}

带参数的混合

参数混合可以接收传入的值,动态生成样式,就像函数一样。

.shadow(@x: 0, @y: 2px, @blur: 4px, @color: rgba(0,0,0,.2)) {
  box-shadow: @x @y @blur @color;
}

.modal {
  .shadow(0, 4px, 8px, rgba(0,0,0,.3));
}

@arguments 变量

在混合内部,@arguments 代表所有传入的参数,可以一次性赋值给属性。

.box-shadow(@args) {
  -webkit-box-shadow: @arguments;
  box-shadow: @arguments;
}
.element {
  .box-shadow(2px 2px 5px #999);
}

模式匹配与守卫

通过给混合名称设置不同的参数签名,可以根据参数个数或类型进行匹配。结合 when 关键字,还能实现条件判断。

// 根据亮度设置文字颜色
.text-color(@bg) when (lightness(@bg) >= 50%) {
  color: #333;
}
.text-color(@bg) when (lightness(@bg) < 50%) {
  color: #fff;
}

.header {
  background: #444;
  .text-color(#444);
}

嵌套:反映 HTML 结构,减少重复

Less 允许将子选择器写在父选择器内部,自动生成后代、父子组合选择器。配合 & 符号,可以精确控制伪类、伪元素或与父级拼接的选择器。

.nav {
  background: #222;
  ul {
    margin: 0;
    padding: 0;
    li {
      display: inline-block;
      a {
        color: white;
        &:hover {
          color: #3b82f6;
        }
      }
    }
  }
  &-fixed {
    position: fixed;
    top: 0;
  }
}

编译后的 CSS:

.nav { background: #222; }
.nav ul { margin: 0; padding: 0; }
.nav ul li { display: inline-block; }
.nav ul li a { color: white; }
.nav ul li a:hover { color: #3b82f6; }
.nav-fixed { position: fixed; top: 0; }

合理使用嵌套能让样式表的结构更接近 HTML,但过深的嵌套会产生冗余的选择器,一般建议不超过 3 层。

运算与函数:让数值动态计算

Less 支持数值之间的加减乘除运算,并且会自动处理单位转换。配合内置的颜色、数学、字符串函数,能实现复杂的动态样式。

基础运算

@base: 16px;
@padding: @base * 1.5;

.sidebar {
  width: 100% / 3 + 20px;
  padding: @padding;
  line-height: @base * 2;
}

颜色也可以参与运算,Less 会在通道级别进行加减。

@color: #4488cc;
.box {
  background: @color + #111; // 每个通道加 0x11
  border-color: @color - #222;
}

常用内置函数

  • 颜色处理lighten(), darken(), fade(), saturate(), mix()
  • 数学ceil(), floor(), round(), percentage()
  • 字符串escape(), replace()
  • 列表length(), extract()
@primary: #3b82f6;
.btn {
  background: @primary;
  &:hover {
    background: lighten(@primary, 10%);
  }
  &:active {
    background: darken(@primary, 10%);
  }
}

继承:精简生成的 CSS

与混合复制属性不同,继承(extend)会在编译时将多个选择器分组,共享相同的属性集合,从而减少重复代码。

.message {
  padding: 10px;
  border: 1px solid #ddd;
}
.success {
  &:extend(.message);
  border-color: green;
}
.error {
  &:extend(.message);
  border-color: red;
}

编译后:

.message,
.success,
.error {
  padding: 10px;
  border: 1px solid #ddd;
}
.success { border-color: green; }
.error { border-color: red; }

extend 相比混合不会产生多个副本,更适合那些需要严格精简 CSS 体积的场景。但要注意,它无法像带参数的混合那样传递变量。

导入与模块化

当项目样式变得庞大,可以将代码拆分为多个 Less 文件。使用 @import 可以引入其他模块,并且支持将导入文件合并为单一 CSS 输出,减少 HTTP 请求。

// variables.less
@brand-color: #e11d48;

// mixins.less
.rounded(@radius: 4px) {
  border-radius: @radius;
}

// main.less
@import "variables";
@import "mixins";

.header {
  color: @brand-color;
  .rounded(8px);
}

如果希望被导入的文件只在编译时使用而不输出 CSS,可以将其命名为 _file.less 或使用 (reference) 选项导入。

@import (reference) "my-mixins";

命名空间与访问器

当多个混合放在一个模块中,为了避免名称冲突或按功能分组,可以使用命名空间。通过 #namespace > .mixin 的方式来引用。

#utils {
  .center() {
    margin-left: auto;
    margin-right: auto;
  }
  .hide() {
    display: none;
  }
}

.container {
  #utils > .center();
}

循环与递归生成样式

Less 虽然没有传统的循环语句,但可以利用递归混合配合守卫条件来生成重复的规则,例如生成一套网格类。

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

上面的代码将生成 .col-1.col-12 并自动计算宽度。

总结与最佳实践

  • 优先使用变量:将颜色、字号、间距等可复用的设计标记定义为变量,构建主题系统。
  • 混合优于复制:将重复的样式片段抽象为参数化混合,避免代码冗余。
  • 合理嵌套:通过嵌套映射 DOM 层级,但避免超过 3 层深度。
  • 需要精简时使用继承:当多个选择器共享完全相同的属性集时,用 extend 代替混合,可优化输出体积。
  • 模块化拆分:将全局变量、混合、基础样式、组件样式分别存放在不同文件,通过 @import 组织。
  • 保持兼容性:利用 Autoprefixer 等工具与 Less 配合,自动添加浏览器前缀;避免使用现代 CSS 尚未广泛支持的属性作为运算对象。

Less 作为动态样式表语言,并不会增加项目复杂度,反而能通过清晰的工程化手段让 CSS 更易于维护。现在,你可以将现有的 CSS 文件直接改名为 .less 开始尝试,逐步引入上述特性,感受预处理器带来的效率提升。