普通视图

发现新文章,点击刷新页面。
今天 — 2026年4月10日首页

学习Less,看这篇就够了(从入门到实战)

2026年4月10日 09:58

Less(Leaner Style Sheets)是CSS预处理器,在原生CSS基础上增加变量、嵌套、混合、函数、运算、模块化等编程特性,让CSS更易维护、复用、扩展,最终编译成标准CSS运行。本文从环境搭建、核心语法、进阶技巧、实战规范全流程覆盖,新增多个优雅使用案例(含Less源码与编译后CSS对比),直接上手可用。

一、Less基础:是什么、为什么、怎么用

1.1 核心优势(为什么用Less)

  • 变量统一管理:颜色、尺寸、字体等全局配置,一改全改
  • 嵌套结构:完全匹配HTML层级,代码更直观、减少重复选择器
  • 混合(Mixin):复用样式片段,像函数一样传参
  • 运算/函数:支持加减乘除、颜色明暗、单位转换
  • 模块化:拆分文件、导入合并,便于团队协作与维护
  • 兼容原生CSS:所有CSS代码可直接写在Less中,零学习门槛

1.2 环境搭建(3种方式,最快1分钟)

方式1:浏览器直接运行(学习/原型)


<!-- 1. 引入Less文件,rel必须是stylesheet/less -->
<link rel="stylesheet/less" type="text/css" href="styles.less" />
<!-- 2. 引入Less编译器(CDN,已替换为可用链接) -->
<script src="https://cdn.bootcdn.net/ajax/libs/less.js/4.2.0/less.min.js"></script>

⚠️ 仅适合开发调试,生产环境禁止使用(性能差、依赖JS);原CDN链接报错“link dead”,已替换为稳定可用版本

方式2:VSCode自动编译(推荐,日常开发)

  1. 安装插件:Easy LESS
  2. 新建.less文件,保存时自动生成同名.css
  3. 配置(可选,settings.json):

"less.compile": {
  "out": "../css/", // 输出到css文件夹
  "compress": true, // 压缩CSS
  "sourceMap": false
}

方式3:命令行编译(项目构建)

  1. 安装Node.js,全局安装Less:

npm install -g less
lessc -v # 验证安装
  1. 编译命令:

lessc styles.less styles.css # 基础编译
lessc styles.less styles.min.css --compress # 压缩输出

二、Less核心语法(必掌握,直接套用)

2.1 变量(@变量名:值)—— 统一管理,一改全改

变量以@开头,可存颜色、尺寸、字体、路径等,支持插值(选择器、属性、URL)。


// 1. 基础变量定义(语义化命名,便于维护)
@primary: #2563eb; // 主色
@success: #16a34a; // 成功色
@font-size: 16px; // 基础字体
@spacing: 20px; // 基础间距
@img-path: "../images"; // 图片路径

// 2. 变量使用(结合运算,减少硬编码)
.btn {
  background: @primary;
  font-size: @font-size;
  padding: @spacing/2; // 10px,无需手动计算
  margin: @spacing;
}

// 3. 变量插值(复用选择器、属性、URL,避免重复书写)
@selector: card;
@prop: width;
.@{selector} { // 编译为 .card
  @{prop}: 300px; // 编译为 width:300px
  background: url("@{img-path}/bg.png");
}

编译后CSS:


.btn {
  background: #2563eb;
  font-size: 16px;
  padding: 10px;
  margin: 20px;
}
.card {
  width: 300px;
  background: url("../images/bg.png");
}

优雅要点:变量语义化命名,通过插值复用选择器和路径,运算替代硬编码,后续修改主色、间距时,仅需修改变量值,无需逐行修改样式。

2.2 嵌套规则(&父选择器)—— 匹配HTML结构,告别重复

Less允许选择器嵌套,&代表当前父选择器,用于伪类、交集选择器、兄弟选择器,避免重复书写父选择器。


// HTML结构:<div class="header"><nav class="nav"><a href="#" class="active">首页</a></nav></div>
.header {
  width: 100%;
  height: 60px;
  background: #fff;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1); // 增加阴影,提升质感
  .nav {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
    a {
      color: #333;
      text-decoration: none;
      padding: 0 @spacing/2; // 复用间距变量
      margin: 0 @spacing;
      // & 代表父选择器 .nav a,避免书写 .nav a:hover
      &:hover { 
        color: @primary;
        transition: color 0.3s ease; // 过渡效果,更优雅
      }
      &.active { 
        font-weight: bold; 
        color: @primary;
        border-bottom: 2px solid @primary;
      }
    }
  }
}

编译后CSS(对比:选择器自动拼接,无需手动重复):


.header {
  width: 100%;
  height: 60px;
  background: #fff;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.header .nav {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
}
.header .nav a {
  color: #333;
  text-decoration: none;
  padding: 0 10px;
  margin: 0 20px;
}
.header .nav a:hover {
  color: #2563eb;
  transition: color 0.3s ease;
}
.header .nav a.active {
  font-weight: bold;
  color: #2563eb;
  border-bottom: 2px solid #2563eb;
}

优雅要点:嵌套结构与HTML完全对应,可读性极强;&的使用避免重复书写父选择器(如.header .nav a),同时结合过渡效果,提升交互质感。

2.3 混合(Mixin)—— 复用样式,支持传参(核心)

Mixin是可复用的样式片段,带()不输出到CSS,不带()会输出;支持参数、默认值、条件判断,可封装公共样式,避免重复编码。

(1)基础Mixin(无参)—— 封装公共样式


// 定义:清除浮动(公共Mixin,可全局调用)
.clearfix() {
  &::after {
    content: "";
    display: block;
    clear: both;
    height: 0;
    visibility: hidden;
  }
}

// 定义:居中布局(公共Mixin,复用性强)
.center() {
  display: flex;
  justify-content: center;
  align-items: center;
}

// 使用:多个容器复用,无需重复书写样式
.container {
  .clearfix(); // 调用清除浮动
  width: 1200px;
  margin: 0 auto;
}
.modal {
  .center(); // 调用居中布局
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0,0,0,0.5);
}

编译后CSS(对比:Mixin样式自动注入,无需重复书写):


.container {
  width: 1200px;
  margin: 0 auto;
}
.container::after {
  content: "";
  display: block;
  clear: both;
  height: 0;
  visibility: hidden;
}
.modal {
  display: flex;
  justify-content: center;
  align-items: center;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0,0,0,0.5);
}

(2)带参数Mixin(默认值、多参数)—— 动态生成样式


// 定义:按钮样式(带参数+默认值,灵活适配不同场景)
.btn(@bg: @primary, @color: #fff, @radius: 4px, @padding: 8px 16px) {
  display: inline-block;
  padding: @padding;
  background: @bg;
  color: @color;
  border-radius: @radius;
  cursor: pointer;
  border: none;
  outline: none;
  transition: all 0.3s ease; // 统一过渡效果
  &:hover { 
    filter: brightness(0.9); // hover变暗,无需单独写样式
    transform: translateY(-2px); // 轻微上浮,提升交互
  }
  &:active {
    transform: translateY(0);
  }
}

// 使用:按需传参,无需重复书写按钮基础样式
.btn-primary { .btn(); } // 使用默认值(主色按钮)
.btn-success { .btn(@success); } // 传单个参数(成功色按钮)
.btn-round { .btn(@primary, #fff, 50%, 10px 20px); } // 传全部参数(圆形按钮)
.btn-small { .btn(@primary, #fff, 4px, 4px 8px); } // 传部分参数(小尺寸按钮)

编译后CSS(对比:自动生成不同样式的按钮,代码简洁):


.btn-primary {
  display: inline-block;
  padding: 8px 16px;
  background: #2563eb;
  color: #fff;
  border-radius: 4px;
  cursor: pointer;
  border: none;
  outline: none;
  transition: all 0.3s ease;
}
.btn-primary:hover {
  filter: brightness(0.9);
  transform: translateY(-2px);
}
.btn-primary:active {
  transform: translateY(0);
}

.btn-success {
  display: inline-block;
  padding: 8px 16px;
  background: #16a34a;
  color: #fff;
  border-radius: 4px;
  cursor: pointer;
  border: none;
  outline: none;
  transition: all 0.3s ease;
}
.btn-success:hover {
  filter: brightness(0.9);
  transform: translateY(-2px);
}
.btn-success:active {
  transform: translateY(0);
}

.btn-round {
  display: inline-block;
  padding: 10px 20px;
  background: #2563eb;
  color: #fff;
  border-radius: 50%;
  cursor: pointer;
  border: none;
  outline: none;
  transition: all 0.3s ease;
}
.btn-round:hover {
  filter: brightness(0.9);
  transform: translateY(-2px);
}
.btn-round:active {
  transform: translateY(0);
}

.btn-small {
  display: inline-block;
  padding: 4px 8px;
  background: #2563eb;
  color: #fff;
  border-radius: 4px;
  cursor: pointer;
  border: none;
  outline: none;
  transition: all 0.3s ease;
}
.btn-small:hover {
  filter: brightness(0.9);
  transform: translateY(-2px);
}
.btn-small:active {
  transform: translateY(0);
}

(3)命名空间(组织Mixin,避免冲突)


// 命名空间:统一管理公共Mixin,避免与业务样式冲突
#utils() { // 带(),不输出到CSS
  .clearfix() { 
    &::after {
      content: "";
      display: block;
      clear: both;
      height: 0;
      visibility: hidden;
    }
  }
  .center() { 
    display: flex;
    justify-content: center;
    align-items: center; 
  }
  .shadow() { // 新增阴影Mixin
    box-shadow: 0 2px 12px rgba(0,0,0,0.1);
  }
}

// 调用:通过命名空间调用,清晰区分公共样式与业务样式
.box { 
  #utils.center(); 
  #utils.shadow();
  width: 300px;
  height: 200px;
  background: #fff;
}

编译后CSS:


.box {
  display: flex;
  justify-content: center;
  align-items: center;
  box-shadow: 0 2px 12px rgba(0,0,0,0.1);
  width: 300px;
  height: 200px;
  background: #fff;
}

2.4 运算(+ - * /)—— 自动计算,减少手动计算

支持颜色、数值、单位运算,Less自动处理单位(优先左侧单位),避免手动计算错误,代码更优雅。


@base: 20px;
@width: 1000px;
@card-width: @width / 5; // 200px,自动计算栅格宽度
@light-primary: lighten(@primary, 10%); // 主色变亮10%,无需手动计算色值

.box {
  width: @width - 40px; // 960px,自适应宽度
  padding: @base * 1.5; // 30px,间距按比例调整
  margin: (@base / 2); // 10px,统一间距
}
.card {
  width: @card-width;
  background: @light-primary;
  margin: @base;
}

⚠️ 除法建议加括号:(100px / 2),避免与CSS语法冲突

编译后CSS(对比:自动计算数值和颜色,无需手动计算):


.box {
  width: 960px;
  padding: 30px;
  margin: 10px;
}
.card {
  width: 200px;
  background: #3b82f6; // 自动计算的亮主色
  margin: 20px;
}

2.5 内置函数—— 颜色、字符串、数学处理(常用)

Less提供大量内置函数,无需定义直接用,提升效率,让样式更优雅。


// 颜色函数(最常用,自动处理色值)
@primary: #2563eb;
@dark-primary: darken(@primary, 10%); // 主色变暗10%
@fade-primary: fade(@primary, 50%); // 主色半透明
@saturate-primary: saturate(@primary, 20%); // 主色增加饱和度

// 数学函数(自动处理数值)
@base-font: 16px;
@title-font: ceil(@base-font * 1.5); // 24px,向上取整
@sub-font: floor(@base-font * 0.8); // 12px,向下取整

// 使用:结合函数和变量,样式更灵活
.title {
  font-size: @title-font;
  color: @dark-primary;
}
.sub-title {
  font-size: @sub-font;
  color: @fade-primary;
}
.btn {
  background: @saturate-primary;
  &:hover {
    background: @dark-primary;
  }
}

编译后CSS:


.title {
  font-size: 24px;
  color: #1d4ed8; // 变暗后的主色
}
.sub-title {
  font-size: 12px;
  color: rgba(37, 99, 235, 0.5); // 半透明主色
}
.btn {
  background: #1d4ed8; // 增加饱和度后的主色
}
.btn:hover {
  background: #1d4ed8;
}

2.6 导入(@import)—— 模块化拆分,代码解耦

拆分变量、Mixin、公共样式,通过@import合并,支持省略.less后缀,让代码结构更清晰,便于维护。


// 1. 拆分文件(按功能拆分,各司其职)
// variables.less → 全局变量(单独管理,一改全改)
@primary: #2563eb;
@font-size: 16px;
@spacing: 20px;

// mixins.less → 公共混合(单独管理,全局复用)
.clearfix() { ... }
.btn(@bg: @primary) { ... }
.center() { ... }

// base.less → 基础样式(reset、全局样式)
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body {
  font-family: "Microsoft YaHei", sans-serif;
  font-size: @font-size;
  color: #333;
}

// 2. 主文件导入(统一入口,结构清晰)
@import "variables"; // 省略.less
@import "mixins";
@import "base";

// 编写业务样式(仅关注业务,无需关注公共样式)
.header {
  .clearfix();
  height: 60px;
  .nav {
    .center();
    a {
      color: #333;
      &:hover { color: @primary; }
    }
  }
}

⚠️ @import (reference) "mixins.less"; → 仅导入Mixin,不输出到CSS

编译后CSS(对比:所有导入的样式自动合并,结构清晰):


* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body {
  font-family: "Microsoft YaHei", sans-serif;
  font-size: 16px;
  color: #333;
}
.header {
  height: 60px;
}
.header::after {
  content: "";
  display: block;
  clear: both;
  height: 0;
  visibility: hidden;
}
.header .nav {
  display: flex;
  justify-content: center;
  align-items: center;
}
.header .nav a {
  color: #333;
}
.header .nav a:hover {
  color: #2563eb;
}

2.7 作用域与注释

  • 作用域:就近原则,局部变量覆盖全局变量,类似JS,可灵活控制变量作用范围

// 全局变量(整个项目可用)
@color: red;

// 局部变量(仅在.box内可用,不影响全局)
.box {
  @color: blue;
  color: @color; // blue(局部优先)
}
// 其他模块仍使用全局变量
.text {
  color: @color; // red
}

编译后CSS:


.box {
  color: blue;
}
.text {
  color: red;
}
  • 注释:

    • 单行注释:// 注释 → 编译后不保留(用于开发备注,不污染生产CSS)
    • 多行注释:/* 注释 */ → 编译后保留(用于生产环境备注,如版权信息)

三、Less进阶技巧(提升效率,避坑)

3.1 父选择器&高级用法


// 1. 前缀拼接(批量生成同类样式,避免重复)
.btn {
  display: inline-block;
  padding: 8px 16px;
  border-radius: 4px;
  &-primary { background: @primary; color: #fff; } // .btn-primary
  &-success { background: @success; color: #fff; } // .btn-success
  &-warning { background: #f59e0b; color: #fff; } // .btn-warning
  &-disabled { background: #ccc; color: #666; cursor: not-allowed; } // .btn-disabled
}

// 2. 多层嵌套&(精准定位子元素,避免冗长选择器)
.list {
  width: 100%;
  &-item {
    padding: @spacing;
    border-bottom: 1px solid #eee;
    &:last-child { border-bottom: none; } // .list-item:last-child
    &-title { font-weight: bold; color: #333; } // .list-item-title
    &-content { color: #666; margin-top: 8px; } // .list-item-content
  }
}

编译后CSS(对比:自动拼接选择器,批量生成样式,代码简洁):


.btn {
  display: inline-block;
  padding: 8px 16px;
  border-radius: 4px;
}
.btn-primary {
  background: #2563eb;
  color: #fff;
}
.btn-success {
  background: #16a34a;
  color: #fff;
}
.btn-warning {
  background: #f59e0b;
  color: #fff;
}
.btn-disabled {
  background: #ccc;
  color: #666;
  cursor: not-allowed;
}

.list {
  width: 100%;
}
.list-item {
  padding: 20px;
  border-bottom: 1px solid #eee;
}
.list-item:last-child {
  border-bottom: none;
}
.list-item-title {
  font-weight: bold;
  color: #333;
}
.list-item-content {
  color: #666;
  margin-top: 8px;
}

3.2 条件Mixin(when)—— 动态生成样式


// 定义:根据尺寸生成不同按钮(条件判断,灵活适配)
.btn(@size) when (@size = large) {
  padding: 12px 24px;
  font-size: 18px;
  border-radius: 6px;
}
.btn(@size) when (@size = small) {
  padding: 4px 8px;
  font-size: 14px;
  border-radius: 3px;
}
// 新增条件:根据主题生成不同颜色
.btn(@size, @theme) when (@theme = dark) {
  .btn(@size);
  background: #333;
  color: #fff;
}

// 使用:按需传入条件,自动生成对应样式
.btn-lg { .btn(large); } // 大尺寸按钮
.btn-sm { .btn(small); } // 小尺寸按钮
.btn-lg-dark { .btn(large, dark); } // 大尺寸深色按钮

编译后CSS:


.btn-lg {
  padding: 12px 24px;
  font-size: 18px;
  border-radius: 6px;
}
.btn-sm {
  padding: 4px 8px;
  font-size: 14px;
  border-radius: 3px;
}
.btn-lg-dark {
  padding: 12px 24px;
  font-size: 18px;
  border-radius: 6px;
  background: #333;
  color: #fff;
}

3.3 循环(for)—— 批量生成样式(Less 3.9+)


// 生成1-5列栅格(循环遍历,无需手动写5个样式)
.generate-columns(@n, @i: 1) when (@i =< @n) {
  .col-@{i} {
    width: (@i * 100% / @n);
    float: left;
    padding: @spacing/2;
    box-sizing: border-box;
  }
  .generate-columns(@n, @i + 1); // 递归循环
}
.generate-columns(5); // 生成col-1到col-5

// 生成不同尺寸的margin样式(批量生成,复用性强)
.generate-margin(@n, @i: 1) when (@i =< @n) {
  .mt-@{i} { margin-top: @i * 8px; }
  .mb-@{i} { margin-bottom: @i * 8px; }
  .generate-margin(@n, @i + 1);
}
.generate-margin(5); // 生成mt-1~mt-5、mb-1~mb-5

编译后CSS(对比:自动生成10个margin样式+5个栅格样式,无需手动书写):


.col-1 {
  width: 20%;
  float: left;
  padding: 10px;
  box-sizing: border-box;
}
.col-2 {
  width: 40%;
  float: left;
  padding: 10px;
  box-sizing: border-box;
}
.col-3 {
  width: 60%;
  float: left;
  padding: 10px;
  box-sizing: border-box;
}
.col-4 {
  width: 80%;
  float: left;
  padding: 10px;
  box-sizing: border-box;
}
.col-5 {
  width: 100%;
  float: left;
  padding: 10px;
  box-sizing: border-box;
}

.mt-1 { margin-top: 8px; }
.mb-1 { margin-bottom: 8px; }
.mt-2 { margin-top: 16px; }
.mb-2 { margin-bottom: 16px; }
.mt-3 { margin-top: 24px; }
.mb-3 { margin-bottom: 24px; }
.mt-4 { margin-top: 32px; }
.mb-4 { margin-bottom: 32px; }
.mt-5 { margin-top: 40px; }
.mb-5 { margin-bottom: 40px; }

3.4 映射(Maps)—— 像对象一样取值(Less 3.5+)


// 定义颜色映射(类似JS对象,统一管理所有颜色,便于查找和修改)
@colors: {
  primary: #2563eb;
  success: #16a34a;
  warning: #f59e0b;
  danger: #ef4444;
  dark: #333;
  light: #f5f5f5;
};

// 定义尺寸映射(统一管理尺寸,避免硬编码)
@sizes: {
  small: 14px;
  base: 16px;
  large: 18px;
  xlarge: 24px;
};

// 使用:通过映射取值,代码更简洁,维护更方便
.btn {
  font-size: @sizes[base];
  &-primary { background: @colors[primary]; }
  &-success { background: @colors[success]; }
  &-warning { background: @colors[warning]; }
}
.title {
  font-size: @sizes[xlarge];
  color: @colors[dark];
}

编译后CSS:


.btn {
  font-size: 16px;
}
.btn-primary {
  background: #2563eb;
}
.btn-success {
  background: #16a34a;
}
.btn-warning {
  background: #f59e0b;
}
.title {
  font-size: 24px;
  color: #333;
}

四、实战规范与常见问题(避坑指南)

4.1 项目规范(推荐)

  1. 文件结构:

src/
├── less/
│   ├── variables.less   # 全局变量(颜色、尺寸、字体)
│   ├── mixins.less      # 公共混合(清除浮动、按钮、居中)
│   ├── base.less        # 基础样式(reset、全局)
│   ├── components/      # 组件(按钮、卡片、导航)
│   └── main.less        # 主入口(导入所有)
  1. 命名:变量用@xxx-xxx(@primary-color),Mixin用小驼峰/短横线,语义化

4.2 常见问题与解决

  1. 嵌套过深:最多3层,避免编译后选择器过长、性能差
  2. 变量污染:全局变量放单独文件,局部变量仅在模块内使用
  3. 编译报错:检查括号、分号、变量定义,优先用Easy LESS实时提示
  4. 单位冲突:运算时统一单位,或用unit()函数转换

五、Less vs Sass(快速对比,选择更合适)

特性 Less Sass
变量符号 @ $
编译环境 Node.js/浏览器 Ruby/Node.js
语法 接近CSS,易上手 缩进/花括号两种
循环/条件 支持(Less 3.9+) 原生支持,更强大
生态 轻量,适合中小型项目 功能全,适合大型项目

六、总结与下一步

Less核心就是把CSS变成可维护的代码:变量统一、嵌套清晰、Mixin复用、函数简化、模块化拆分。新增的优雅案例均贴合实际开发,通过Less源码与编译后CSS对比,可清晰看到Less如何简化编码、提升效率。

❌
❌