文章目录
-
- [一、Less 常用语法](#一、Less 常用语法)
-
- [1. 变量 `@`](#1. 变量
@) - [2. 嵌套 & 父选择器 `&`](#2. 嵌套 & 父选择器
&) - [3. Mixin(混合)](#3. Mixin(混合))
- [4. 命名空间](#4. 命名空间)
- [5. 运算 & 字符串插值](#5. 运算 & 字符串插值)
- [6. 条件混合(Guards)](#6. 条件混合(Guards))
- [7. 循环(递归 mixin)](#7. 循环(递归 mixin))
- [8. `extend` 继承](#8.
extend继承) - [9. 模块引入](#9. 模块引入)
- [10. 内建函数(常用)](#10. 内建函数(常用))
- [11. JS 求值(Less 特有,但 4.0 起默认关闭)](#11. JS 求值(Less 特有,但 4.0 起默认关闭))
- [1. 变量 `@`](#1. 变量
- [二、Less vs SCSS 核心区别](#二、Less vs SCSS 核心区别)
-
- [1. 语法差异速查](#1. 语法差异速查)
- [2. 能力强弱对比](#2. 能力强弱对比)
- [3. 一个典型对比示例](#3. 一个典型对比示例)
- 三、适用场景
-
- [优先选 **SCSS**](#优先选 SCSS)
- [优先选 **Less**](#优先选 Less)
- 都能用,不必纠结
- 当下趋势(2024-2026)参考
一、Less 常用语法
1. 变量 @
css
@primary-color: #1677ff;
@base-font: 14px;
@radius: 4px;
.btn {
color: @primary-color;
font-size: @base-font;
border-radius: @radius;
}
- 变量符号是
@(SCSS 是$)。 - 作用域:惰性求值 ------ 同一作用域内后定义的会覆盖前面的("延迟加载")。
css
@color: red;
.box { color: @color; } // 实际是 blue
@color: blue;
2. 嵌套 & 父选择器 &
css
.card {
padding: 16px;
.title {
font-weight: bold;
}
&:hover {
background: #f5f5f5;
}
&__header { // BEM 拼接
border-bottom: 1px solid #eee;
}
}
3. Mixin(混合)
Less 的 mixin 就是一个普通的类选择器:
css
// 无参 mixin ------ 直接定义一个类
.clearfix() {
&::after {
content: '';
display: block;
clear: both;
}
}
// 带参 + 默认值
.flex(@direction: row, @justify: center, @align: center) {
display: flex;
flex-direction: @direction;
justify-content: @justify;
align-items: @align;
}
.container {
.clearfix();
.flex(row, space-between);
}
关键差异 :mixin 名后带
()表示不输出自身、仅可被调用;不带()则同时会输出为普通类。
css
.btn { color: red; } // 既是普通类,也可作为 mixin 调用
.box { .btn; } // 把 .btn 的样式拷进 .box
4. 命名空间
css
#theme {
.primary() { color: #1677ff; }
.danger() { color: #ff4d4f; }
}
.btn {
#theme > .primary();
}
5. 运算 & 字符串插值
css
.box {
width: 100px + 50px; // 150px
height: 100% / 3; // 33.3333%
margin: (@base-font * 2);
}
// 字符串插值用 @{} (SCSS 用 #{})
@prefix: app;
.@{prefix}-card {
background: url('/img/@{prefix}-bg.png');
}
6. 条件混合(Guards)
Less 没有 @if,用 mixin Guard 模拟条件:
css
.text(@size) when (@size > 16px) {
font-weight: bold;
font-size: @size;
}
.text(@size) when (@size <= 16px) {
font-size: @size;
}
.title { .text(20px); } // 走第一个
.body { .text(14px); } // 走第二个
支持的判断:when (@x > 1)、when (iscolor(@x))、when not (...)、when (default())。
7. 循环(递归 mixin)
Less 没有 @for / @each,用递归 mixin 实现:
css
.loop(@i) when (@i > 0) {
.col-@{i} {
width: (@i * 20%);
}
.loop(@i - 1);
}
.loop(5);
遍历列表:
css
@colors: primary #1677ff, success #52c41a, danger #ff4d4f;
.each(@i: 1) when (@i <= length(@colors)) {
@pair: extract(@colors, @i);
@name: extract(@pair, 1);
@value: extract(@pair, 2);
.text-@{name} { color: @value; }
.each(@i + 1);
}
.each();
对比 SCSS 的
@each $name, $color in $colors------ Less 写起来明显繁琐。
8. extend 继承
css
.btn-base {
display: inline-block;
padding: 8px 16px;
}
.btn-primary {
&:extend(.btn-base);
background: #1677ff;
}
// 或:
.btn-default:extend(.btn-base) {
background: #f5f5f5;
}
9. 模块引入
css
@import 'variables.less'; // 普通引入
@import (reference) 'mixins'; // 仅引用 mixin/变量,不输出
@import (once) 'reset'; // 只引入一次(默认行为)
@import (less) 'foo.css'; // 当作 less 处理
Less 只有
@import,没有 SCSS 的@use/@forward命名空间隔离机制。
10. 内建函数(常用)
css
.box {
color: lighten(#1677ff, 10%);
background: darken(#1677ff, 10%);
border: 1px solid fade(#000, 20%); // rgba(0,0,0,0.2)
color: mix(#fff, #1677ff, 50%);
width: percentage(0.5); // 50%
height: round(3.7); // 4
}
颜色 / 数学函数和 SCSS 几乎一一对应。
11. JS 求值(Less 特有,但 4.0 起默认关闭)
css
@width: `Math.round(100 / 3)`; // 需要开启 javascriptEnabled
不推荐使用,可移植性差,且默认禁用。
二、Less vs SCSS 核心区别
1. 语法差异速查
| 语法点 | SCSS | Less |
|---|---|---|
| 变量 | $color: red; |
@color: red; |
| 字符串插值 | #{$var} |
@{var} |
| 父选择器 | & |
& |
| 引入 | @use / @forward / @import |
@import |
| Mixin 定义 | @mixin name() {} |
.name() {} |
| Mixin 调用 | @include name() |
.name() |
| 函数 | @function name() { @return ... } |
无(用 mixin + 返回变量近似) |
| 条件 | @if / @else if / @else |
mixin Guard when (...) |
| 循环 | @for / @each / @while |
递归 mixin |
| Map / 字典 | (key: val, ...) 原生支持 |
无(只能用列表 + extract 模拟) |
| 列表 | (1, 2, 3) + 丰富 API |
类似但 API 少 |
| 继承 | @extend .x / 占位符 %x |
&:extend(.x),无占位符 |
| 命名空间 | @use './m' as m; → m.$x |
#ns { .mixin() {} } |
| 变量作用域 | 词法 + 自上而下求值 | 惰性求值(同作用域内最后一次为准) |
| 编译器 | Dart Sass(JS 实现),主流 | less.js(JS) |
| 内建模块 | sass:math/color/list/map/string/meta |
内建函数全局可用 |
2. 能力强弱对比
逻辑表达能力(强 → 弱)
SCSS (@function/@for/@each/Map) >> Less (mixin Guard + 递归)
学习曲线(陡 → 缓)
SCSS(概念多:@use/@forward、模块、Map、@extend 占位符)
> Less(几乎就是 CSS + 变量 + mixin,10 分钟上手)
工程化 / 模块化
SCSS(@use 命名空间隔离、@forward 重新导出)>> Less(仅 @import)
社区与生态
SCSS(Bootstrap 5+、Tailwind 配套、绝大多数组件库)
> Less(Ant Design、阿里系组件库)
3. 一个典型对比示例
生成栅格类:
css
// SCSS:清晰简洁
@for $i from 1 through 12 {
.col-#{$i} { width: percentage($i / 12); }
}
css
// Less:必须递归 mixin
.gen(@i) when (@i > 0) {
.col-@{i} { width: percentage(@i / 12); }
.gen(@i - 1);
}
.gen(12);
遍历主题色:
css
// SCSS
$colors: (primary: blue, danger: red);
@each $name, $c in $colors {
.text-#{$name} { color: $c; }
}
css
// Less
@colors: primary blue, danger red;
.loop(@i: 1) when (@i <= length(@colors)) {
@p: extract(@colors, @i);
.text-@{extract(@p, 1)} { color: extract(@p, 2); }
.loop(@i + 1);
}
.loop();
三、适用场景
优先选 SCSS
- 复杂业务系统 / 中后台:需要遍历配置生成样式(栅格、间距、主题色阶、工具类)。
- 设计系统 / 组件库 :需要 Map 管理 token、
@use做模块化、@function抽象。 - 多主题、可定制 UI 库:SCSS Map 配合 CSS 变量产出多套主题最顺手。
- 跟 Bootstrap、Tailwind 主题、Element Plus(其底层 SCSS)配合。
- 团队偏后端思维 :
@if / @each / @function写起来更像编程语言。
优先选 Less
- Ant Design (v4 及以前) 二次开发 :AntD 老版本默认 Less,定制主题用
modifyVars。 - 简单项目 / 内部工具站:只需要变量 + 嵌套 + 少量 mixin,Less 上手快、心智负担低。
- 历史项目存量:原项目就是 Less,没必要切换。
- 运行时按需改变量(CDN 引 less.js 实时编译,已较少见)。
- 团队成员对 CSS 更熟,不想多学一套语义。
都能用,不必纠结
- 只是给项目加点变量、嵌套和 mixin。
- 现代项目里两者最终能力差距越来越小 ,因为复杂逻辑通常用:
- CSS 变量 做运行时换肤
- PostCSS / Tailwind / UnoCSS 做工具类
- CSS-in-JS 做组件级样式
当下趋势(2024-2026)参考
| 项目类型 | 主流选择 |
|---|---|
| 新建 Vue 3 项目 | SCSS(Vite 默认推荐,组件库多用 SCSS) |
| 新建 React 项目 | CSS Modules / Tailwind / styled-components,预处理用 SCSS 居多 |
| AntD v4 老项目 | Less(继续用) |
| AntD v5+ 项目 | CSS-in-JS(已抛弃 Less) |
| Element Plus 项目 | SCSS |
| Bootstrap 项目 | SCSS |