主题
Less 的使用(Day19 1/3)
本页对应 Day19_PC项目&Less,共 6 段视频,约 1 小时 2 分。
学习目标
- 能说明 Less 与 CSS 的关系及“浏览器不识别 Less,需编译为 CSS”的流程,并列举至少一种 Less 编译方式。
- 能安装并配置 VS Code 的 Easy Less 插件,实现保存
.less文件时自动生成同名.css文件,并在 HTML 中通过link引入编译后的 CSS。 - 能按入口文件、变量文件、混合文件、重置样式文件的职责拆分 Less 项目结构,并在
index.less中正确使用@import导入后完成编译。 - 能使用 Less 变量、嵌套、混合及两种注释写法编写样式,并判断编译后 CSS 中注释是否保留。
- 能使用 Less 嵌套与 Flex 布局完成 topbar 的左右分区、间距、分隔线,以及 logo 和搜索框的尺寸、外边距、边框、背景色等样式。
- 能通过检查编译后的 CSS 验证变量替换和嵌套选择器结果,定位并修正编译或样式问题。
知识点
一、CSS 预处理器:先理解它解决什么
为什么需要:CSS 不是编程语言,没有变量、表达式、函数、分支和循环。页面里同一个主题红、同一个分割线颜色会反复出现,每次都写十六进制编码既难记又容易写错;重复样式也无法像函数一样复用。
怎么想:Less 的思路不是替代 CSS,而是在 CSS 语法基础上增加编程特性。浏览器只认识 W3C 标准里的 CSS,不认识 Less,所以程序员写 Less,再把它编译成 CSS 给浏览器。课堂图例展示的就是“左侧 Less 代码→编译→右侧纯 CSS”的过程。
怎么做:先建立正确链路:写 .less 文件 → 用工具编译成 .css → HTML 中用 link 引入 CSS。Less 语法兼容 CSS,不会写 Less 特性时可以先写纯 CSS;学习重点是多出来的变量、嵌套、混合、运算等特性。
易错点:不要把 Less 文件直接交给浏览器;不要以为浏览器“运行时会认识 Less”。浏览器端用 Less.js 也能编译,但页面运行时才编译,会影响加载速度,开发学习可演示,实际项目不推荐。
二、整体准备:先搭目录和入口文件
为什么需要:PC 项目会分顶部导航、Logo 与搜索框等多部分。若所有代码堆在一个文件里,后期查找和修改都困难;课堂采用“每完成一部分保存一个文件”的方式,便于对照。
怎么想:把变量、混合、重置样式拆开,再通过一个入口 Less 文件统一导入。编译时只编译入口文件,其他被导入文件不需要单独编译。
怎么做:建立 index.html、index.less、变量文件、混合文件;把 reset.css 的扩展名改为 .less,这样用 @import 导入时会把内容合并进入口文件,而不是在编译结果里保留一条 CSS 的 @import。入口文件可写:
less
@import "variables";
@import "mixins";
@import "reset.less";易错点:变量文件、混合文件不要单独编译;@import 的路径和扩展名要写对;重置样式若仍是 .css,导入行为会和 .less 不同。
三、编译 Less:推荐 VS Code 插件自动编译
为什么需要:浏览器不认识 Less,必须有编译步骤。课堂演示了 Less.js 和 VS Code 插件两种方式,并明确推荐后者。
怎么想:Less.js 方式是在 HTML 的 style 上写 type="text/less",再引入 Less.js;它依赖页面运行时编译,编辑器还会报错。插件方式是在保存 .less 时自动生成同名 .css,HTML 只引入 CSS,页面加载速度不受影响。
怎么做:在 VS Code 扩展中搜索并安装 Easy Less;新建 index.less,按 Ctrl+S 保存,旁边自动生成 index.css;HTML 中写 link 引入编译后的 CSS。调试时先看 CSS 是否生成,再看 HTML 是否引入正确。
易错点:HTML 不要引入 .less;type 或 rel 写错会导致浏览器端编译失败;插件自动编译后,页面用的是 CSS,不要误以为页面直接识别 Less。
四、topbar:用嵌套和 Flex 做左右布局
为什么需要:顶部栏背景横跨整页,但内容需要版心限制宽度;左右两组内容要一端欢迎语、一端导航菜单。
怎么想:外层 .topbar 负责背景和高度,内层 .container 负责 1200px 版心;左右两块放进 Flex 容器,用 justify-content: space-between 分开。导航竖线不额外做元素,直接给 a 加右边框。
怎么做:用 Less 嵌套写:
less
.topbar {
height: 30px;
background: #ea4a36;
.container {
display: flex;
justify-content: space-between;
}
a {
padding: 0 10px;
border-right: 1px solid @sep-color;
&:last-child { border-right: none; }
}
}易错点:&:last-child 要写在 a 的嵌套里,编译后才会排除各自父容器中的最后一个 a;不要给所有 a 都保留右边框。Less 嵌套能折叠代码,但选择器层级要想清楚。
五、Less 注释:两种注释编译结果不同
为什么需要:注释用于说明代码,但 CSS 和 Less 对注释处理不同,需知道哪些会进入编译结果。
怎么想:/* */ 是 CSS 注释,Less 兼容 CSS,所以会原样编译到 CSS;// 是 Less 注释,编译时直接忽略,不进入 CSS。
怎么做:在 .less 中写:
less
/* 会保留到 CSS */
// 不会保留到 CSS保存后对比生成的 .css。
易错点:不要以为所有注释都会保留;实际开发更推荐 //,避免编译结果里堆无用注释。
六、Logo 和搜索框:尺寸、边框与 Flex 收尾
为什么需要:Logo 图片和搜索表单要按设计稿尺寸排布,输入框和按钮还要处理边框、背景、间距及行内元素留白。
怎么想:外层 .header 内放版心,版心用 Flex 两端对齐;Logo 的 a 在 Flex 子项中可设宽高;表单内 input 用 box-sizing: border-box 控制总宽高,按钮设置宽高、背景和文字颜色;表单本身改成 Flex,消除行内换行产生的空白。
怎么做:按课堂要求设置 Logo 宽高 175×56、上下外边距 25、左右 45;输入框宽高 490×32、内边距 0 4px、边框 2px,颜色用变量;按钮 68×32,背景用变量、文字白色;表单 display:flex 并加 margin-top:35px。
易错点:input 不加 border-box 时宽高会把边框和内边距算进去导致超宽;按钮默认盒模型与普通元素不同,要按实际效果核对;输入框的 outline 可设为 none,但不要漏掉边框样式。
为什么需要 Less:先看 CSS 的痛点
为什么需要: CSS 不是编程语言,没有变量、表达式、函数、分支和循环。页面里同一个主题红可能反复出现在边框、背景、按钮上,每次都写十六进制色值,既难记又容易写错;重复样式也只能复制粘贴。
怎么想: 如果 CSS 里也能定义变量、写嵌套、抽公共代码,就能把“主题色、分割线、清除浮动”等重复内容集中管理。Less 就是在 CSS 语法基础上扩展出这些能力,浏览器不直接认识 Less,最终仍要编译成 CSS。
怎么做: 先建立“写 Less → 编译成 CSS → HTML 引入 CSS”的链路,而不是让浏览器直接跑 Less。
易错点: 不要把 Less 当成浏览器原生语言;转写稿里的“light/lets/类次/赖子”都是同音误写,正确是 Less。浏览器只认 CSS。
两种编译方式:less.js 与 Easy Less
为什么需要: 写完 .less 浏览器不认识,必须编译。
怎么想: 学习时可以先用 less.js 在页面里现场编译,便于理解“Less 不是 CSS”;实际开发更推荐编辑器插件自动编译,避免页面运行时编译影响加载速度。
怎么做: 方式一,在 HTML 中写 <style type="text/less">,引入 less.js,再引入 Less 文件;方式二,在 VS Code 安装 Easy Less,新建 .less 文件,保存后自动生成同名 .css,HTML 用 <link> 引入生成的 CSS。
易错点: type="text/less" 不能省;less.js 方式会让 VS Code 报错且增加客户端编译负担;Easy Less 生成的是 CSS,HTML 不要引入 .less。
html
<style type="text/less">
@fcolor: red;
@bcolor: #099;
@len: 100px;
div {
width: @len;
height: @len / 4;
color: @fcolor;
background: @bcolor;
}
</style>
<script src="./less.js"></script>项目文件组织:入口文件统一导入
为什么需要: 变量、混合、重置样式分散时便于维护,但最终只需编译入口文件。
怎么想: 建 index.less 作为入口,建 variables.less 放变量,mixins.less 放混合,把 reset.css 改成 reset.less 再导入。
怎么做: 在 index.less 中 @import 各文件;只编译 index.less。
易错点: 如果 @import "reset.css",CSS 的 @import 可能被原样保留;改成 .less 后内容才会被合并进来。变量文件、混合文件不单独编译。
less
// index.less
@import "./variables.less";
@import "./mixins.less";
@import "./reset.less";Less 注释:两种写法输出不同
为什么需要: 注释影响编译结果和可读性。
怎么想: /* */ 是 CSS 注释,会原样编译到 CSS;// 是 Less 注释,编译时直接忽略。
怎么做: 日常写 Less 推荐 //;需要保留给 CSS 的说明才用 /* */。
易错点: 不要以为所有注释都不会出现在 CSS 中;/* */ 会保留。
less
/* 这条会编译到 CSS */
// 这条不会编译到 CSS变量、嵌套与混合:把重复样式收起来
为什么需要: 主题色、分割线、清除浮动等重复出现。
怎么想: 颜色抽成变量;选择器关系用嵌套表达;公共代码抽成混合。
怎么做: 变量用 @form-color 等命名;嵌套里用 &:not(:last-child) 排除最后一个;混合定义加括号,调用时用 .clearfix();。
易错点: 嵌套过深会难读,要对照编译后的 CSS 理解;混合不加括号可能被直接编译;除法按转写稿演示要用括号包裹。
less
@form-color: #ea4a36;
@sep-color: #aeaeae;
.clearfix() {
&::after {
content: "";
display: block;
clear: both;
}
}
.topbar {
height: 30px;
line-height: 30px;
.container {
display: flex;
justify-content: space-between;
}
a {
padding: 0 10px;
&:not(:last-child) {
border-right: 1px solid @sep-color;
}
}
}在 topbar 与搜索框中应用
为什么需要: 用 Less 组织页面结构,能快速写、方便折叠和复用。
怎么想: topbar 外层背景横跨页面,内部 .container 控制版心;左右用 flex 两端对齐。logo 和搜索框同理,form 变成 flex 去掉换行留白。
怎么做: logo 设宽高和外边距;input 设宽高、内边距、边框和 outline: none;button 设宽高、背景、白字、去边框;form 加 margin-top。
易错点: a 是行内元素,但在 flex 项目里可设宽高;button 默认有边框,要清掉;input 和 button 的盒模型要确认;HTML 只引入编译后的 CSS。
less
.header {
.container {
display: flex;
justify-content: space-between;
}
.logo {
width: 175px;
height: 56px;
margin: 25px 45px;
}
form {
display: flex;
margin-top: 35px;
input {
width: 490px;
height: 32px;
padding: 0 4px;
border: 2px solid @form-color;
outline: none;
}
button {
width: 68px;
height: 32px;
background: @form-color;
color: #fff;
border: none;
}
}
}调试时记住:直接写 type="text/less" 浏览器会报错,引入 less.js 后才生效;Easy Less 保存后看生成的 CSS;页面样式不对时,先看编译结果,再回头改 Less。
课堂画面






代码示例
示例一:Less 变量、运算与两种注释(浏览器端 less.js 直接运行)
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>Less 变量、运算与注释</title>
<!-- 注意:type 必须改成 text/less,默认的 text/css 浏览器只会当普通 CSS 解析 -->
<style type="text/less">
// 这是 Less 注释,编译过程中会被直接丢掉,不会出现在 CSS 里
/* 这是 CSS 注释,会被原样搬进编译后的 CSS 中 */
@fcolor: red; // 文字颜色
@bcolor: #009900; // 背景颜色
@length: 1000px; // 长度
div {
width: @length;
height: (@length / 4); /* 除法必须用小括号括起来,否则不参与运算 */
color: @fcolor;
background: @bcolor;
padding: 10px;
}
</style>
</head>
<body>
<div>我是被 Less 变量控制的盒子</div>
<!-- less.js 放在最后,让它能扫描到页面上面的 text/less 样式 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/less.min.js"></script>
</body>
</html>要点与易错点
<style type="text/less">:浏览器只认 W3C 规定的 CSS,text/less它不认识,所以必须靠less.js在页面运行时把 Less 现场编译成 CSS 再塞回页面。@fcolor / @bcolor / @length:Less 变量的写法是@变量名: 值;,用法和 JS 变量很像,就是为了解决“同一个十六进制颜色反复写、还记不住”的痛点。(@length / 4):Less 里做除法要加小括号,不加括号编译不出来结果,这是最容易踩的坑。- 两种注释:
//是 Less 自己的注释,编译时被忽略;/* */是 CSS 语法,Less 会原样搬运到 CSS 中。写业务代码推荐用//。 - 这种方式只适合学习演示:编译发生在浏览器端,拖慢页面加载速度,而且编辑器里会一直报红(它不认识 Less 语法),实际开发不推荐。
示例二:Less 变量 + 嵌套 + 混合,实现顶部 topbar
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>Topbar:Less 变量、嵌套与混合</title>
<style type="text/less">
// ===== 变量:把反复出现的颜色存起来 =====
@btn-red: #e1251b; // 按钮红
@form-red: #ea4a36; // 表单红(边框、背景都用它)
@sep-color: #eaeaea; // 分割线颜色(以资料色值为准)
// ===== 混合:加小括号就不会被编译输出,只有调用时才生成代码 =====
.clearfix() {
&::after {
content: "";
display: block;
clear: both;
}
}
// ===== 版心:宽度 1200,左右自动 =====
.container {
width: 1200px;
margin: 0 auto;
}
// ===== topbar:嵌套写法,子选择器全写在父级里 =====
.topbar {
height: 30px;
line-height: 30px;
background: @sep-color;
.container {
display: flex;
justify-content: space-between; // 左右两端对齐
}
a {
padding: 0 10px; // 每个 a 左右间距 10px
color: #333;
text-decoration: none;
&:not(:last-child) { // & 代表当前选择器本身
border-right: 1px solid @sep-color; // 用边框做竖线
}
}
}
// 演示混合的调用:谁需要清浮动,就在谁里面 .clearfix();
.row {
.clearfix();
background: @btn-red;
}
</style>
</head>
<body>
<div class="topbar">
<div class="container">
<div class="topbar-left">
欢迎来到商品会,请<a href="#">登录</a><a href="#">免费注册</a>
</div>
<nav class="topbar-nav">
<a href="#">我的订单</a>
<a href="#">我的购物车</a>
</nav>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/less.min.js"></script>
</body>
</html>要点与易错点
- 嵌套:
.topbar { .container { ... } a { ... } }编译出来是.topbar .container、.topbar a,结构写起来跟 HTML 一模一样,编辑器里还能整体折叠,这是 Less 最直观的好处。 &是父选择器的引用:&:not(:last-child)编译成.topbar a:not(:last-child),所以左右两组导航的最后一个a都会被排除,竖线不会多出来。- 竖线不用额外元素,直接给
a加border-right就够了;padding: 0 10px同时给左右两组a加了间距。 - 布局用
display: flex+justify-content: space-between一左一右,比浮动省事;行内元素a在伸缩盒里也可以正常设置间距。 - 混合
.clearfix()后面带括号,表示“只定义不输出”,不调用就不会在 CSS 里生成任何东西;调用方式是写.clearfix();,而不是往 HTML 上叠加类名。 - 变量值请以实际设计稿为准,这里只是把“一个页面就那么几个主色”的思路落下来。
示例三:Easy Less 插件 + 多文件组织(推荐的实际开发方式)
less
/* ========== less/variables.less:只放变量,不产出任何 CSS ========== */
@btn-red: #e1251b;
@form-red: #ea4a36;
@sep-color: #eaeaea;less
/* ========== less/mixins.less:只放混合,不产出任何 CSS ========== */
.clearfix() {
&::after {
content: "";
display: block;
clear: both;
}
}less
/* ========== less/index.less:唯一入口文件,只编译它 ========== */
@import "variables.less"; // 导入变量
@import "mixins.less"; // 导入混合
@import "reset.less"; // 原来的 reset.css 改成 .less,内容才会被内联进来
.page-header {
width: 1200px;
margin: 0 auto;
.clearfix();
.logo {
float: left;
width: 175px;
height: 56px;
margin: 25px 45px; // 上下 25,左右 45
}
.search {
display: flex;
margin-top: 35px;
input {
width: 490px;
height: 32px;
padding: 0 4px;
border: 2px solid @form-red;
box-sizing: border-box;
outline: none;
}
button {
width: 68px;
height: 32px;
color: #fff;
background: @form-red;
border: none;
}
}
}css
/* ========== 保存 index.less 后插件自动生成的 index.css(节选) ==========
注释没了、变量没了、@import 也没了,只剩纯 CSS */
.page-header { width: 1200px; margin: 0 auto; }
.page-header::after { content: ""; display: block; clear: both; }
.page-header .logo { float: left; width: 175px; height: 56px; margin: 25px 45px; }
.page-header .search { display: flex; margin-top: 35px; }
.page-header .search input {
width: 490px; height: 32px; padding: 0 4px;
border: 2px solid #ea4a36; box-sizing: border-box; outline: none;
}
.page-header .search button {
width: 68px; height: 32px; color: #fff; background: #ea4a36; border: none;
}html
<!-- ========== index.html:引入的一定是编译出来的 CSS,不是 less ========== -->
<link rel="stylesheet" href="./css/index.css" />要点与易错点
- 安装 VS Code 扩展 Easy Less 后,只要保存
.less文件,就会在同目录自动生成同名.css,写一次存一次编一次,不用手动点编译按钮。 - HTML 里
link引入的必须是index.css,引index.less浏览器根本不认,等于白写。 @import "reset.css"会原样保留成 CSS 的@import语句,不会被内联;想让它把内容搬进来,就把文件后缀改成.less(Less 完全兼容 CSS 写法)。- 变量文件、混合文件本身不产出任何 CSS:变量不输出,混合加了小括号也不输出,它们只是被入口文件导入使用。
- 只编译入口
index.less,不要一个个去编译variables.less、mixins.less,否则会生成一堆没用的 CSS。 - 编译产物可读性很差(注释全丢),以后排查问题看
.less源文件,不要改.css。 - 这种做法页面最终拿到的就是普通 CSS,不影响加载速度,和直接写 CSS 对浏览器来说没有区别。
常见错误
在 HTML 里用
<style type="text/less">+ less.js 做正式开发- 现象:编辑器满屏红波浪线、首屏样式闪烁/变慢、上线后样式时好时坏。
- 原因:编译发生在浏览器端,页面运行时才把 less 转成 CSS,且编辑器不认识该语法。
- 修法:只把它当课堂演示;实际用 Easy Less 等插件在保存时编译出同名
.css,HTML 里link引入.css。
HTML 里直接
link引入.less文件- 现象:页面完全没样式,控制台无明显 JS 报错。
- 原因:浏览器只认 W3C 标准的 CSS,不认 Less。
- 修法:
link指向编译产物(如css/index.css),源文件less/index.less不参与页面引用。
改完 less 页面没变化,或改着改着样式被“还原”了
- 现象:明明改了代码,刷新无效;过一会儿改动又消失了。
- 原因:改的是编译产物
.css(只读产物),下次保存 less 时被整体覆盖;或改完 less 没保存/插件未生效。 - 修法:约定“只改 less,不改生成的 css”;改完按 Ctrl+S,确认同名 css 同步更新后再刷新。
变量写了却编译报错 / 原样输出
- 现象:
color: color;无效,或提示变量未定义。 - 原因:定义和引用都漏写
@;或变量放在variables.less里但入口文件没@import。 - 修法:定义
@form-red: #e1251b;,引用color: @form-red;;在入口index.less顶部按顺序@import "./variables.less";,路径写对。
- 现象:
除法算不出来,输出成一长串
- 现象:
width: @w/4;编译后仍是1000px/4,没变成250px。 - 原因:Less 中除法需要括号包裹才按运算处理,否则可能被当成 CSS 原样保留。
- 修法:写成
width: (@w / 4);。
- 现象:
定义了清除浮动混合,HTML 加 class 却没效果
- 现象:
.clearfix() { ... }写好了,元素上写class="clearfix"完全没用,产物里也找不到这个类。 - 原因:带括号的混合只“被调用才展开”,不会生成同名 CSS 类。
- 修法:明确用途——给 HTML 用就去掉括号定义成普通类;给 less 复用就在父元素里写
.clearfix();调用。
- 现象:
@import "reset.css"后产物里冒出一条@import- 现象:编译出的 CSS 顶部还留着
@import "reset.css";,样式合并没生效。 - 原因:
.css后缀会被当作普通 CSS 导入而原样保留,不参与 Less 合并。 - 修法:把文件改名为
reset.less再@import "./reset.less";(Less 里可以直接写纯 CSS 内容)。
- 现象:编译出的 CSS 顶部还留着
注释“消失”或“莫名其妙出现在产物里”
- 现象:用
//写的说明在 CSS 里找不到;用/* */写的却在产物里占了一大段。 - 原因:两种注释的编译策略不同,一种编译期丢弃,一种原样搬运。
- 修法:开发说明用
//,需要保留给产物看的(如版权、分区标记)才用/* */。
- 现象:用
嵌套写得很爽,编译后选择器却对不上
- 现象:样式不生效,或误伤了别的元素(如给所有
a都加了右边框,最后一个也带线)。 - 原因:嵌套层级与
&位置写错,编译出的选择器与预期不一致。 - 修法:改完立刻对照生成的 CSS 看选择器;需要排除末项时用
&:not(:last-child)/&:last-child验证产物。
- 现象:样式不生效,或误伤了别的元素(如给所有
练习
最小可运行链路:新建
less/index.less,安装 Easy Less,写一条变量 + 一层嵌套,保存后确认自动生成css/index.css;HTML 用link引入该 CSS,验证页面生效。再用“把 link 改成指向 .less”的方式复现一次失败,记录现象。变量与运算:定义
@w: 1000px、@btn-red、@sep-color,写一个盒子width: (@w / 4)、height: (@w / 8),背景用按钮红;把@w改成800px,只改一处,确认宽高同步变化。混合的两种用法:分别写
.clearfix() { ... }(带括号)和.clearfix { ... }(不带括号),各调用一次。用编译产物说明:为什么前者在 HTML 里加 class 无效、后者会多出一个类;并给出“同一个需求下你会选哪种”的判断依据。注释对比:在同一 less 文件中写一条
//注释和一条/* */注释,保存后逐行比对生成的 CSS,写出两条结论(各自去哪了)。项目改造:把
reset.css改名reset.less,建立index.less作为唯一入口,依次导入变量、混合、reset,HTML 只引index.css;再完成 topbar:整体背景色用变量、高度 30px、左右两块用 flex 两端对齐、右侧每个a左右 10px 间距且用分割线色做右边框、最后一个a不带边框。最后检查产物 CSS 中是否还残留@import。
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | CSS预处理器介绍 | 12:17 |
| 2 | 整体准备 | 09:02 |
| 3 | 编译Less | 18:17 |
| 4 | topbar | 13:03 |
| 5 | Less注释 | 03:46 |
| 6 | logo和搜索框 | 06:32 |
小结
- 浏览器永远只认 CSS,Less 的价值在“写的时候”,交付物始终是编译后的 CSS。
- 客户端 less.js 只适合演示,工程里用编辑器插件(或后续的命令行工具)在保存时自动编译。
- 项目只保留一个入口 less,变量、混合、reset 都通过
@import合并,产物只有一个 CSS 文件。 - 生成的 CSS 视为只读产物:排查问题看 less 源码,不要手改产物。
- 变量最值得抽的是颜色——重复率高、十六进制记不住、改主题时一处生效。
- 带括号的混合不产出 CSS,只有调用才展开;要给 HTML 用就别加括号。
- 嵌套提升可读性与可折叠性,但必须用编译后的选择器验证结果,别凭感觉。
- 注释按用途选:
//不进产物,/* */原样保留。