Less 继承 #
@extend 是 Less 提供的一种样式继承机制,它可以让选择器继承另一个选择器的样式,从而减少 CSS 输出量。
基本用法 #
简单继承 #
less
.error {
color: #dc3545;
border: 1px solid #dc3545;
padding: 10px;
}
.serious-error {
&:extend(.error);
font-weight: bold;
}
编译结果:
css
.error,
.serious-error {
color: #dc3545;
border: 1px solid #dc3545;
padding: 10px;
}
.serious-error {
font-weight: bold;
}
继承语法 #
less
// 语法一:在规则内部
.class1 {
&:extend(.class2);
}
// 语法二:在规则外部
.class1:extend(.class2) {}
// 语法三:继承多个选择器
.class1:extend(.class2 .class3) {}
继承类型 #
精确匹配 #
默认只继承精确匹配的选择器:
less
.a.class {
color: red;
}
.b:extend(.class) {} // 不继承 .a.class
.c:extend(.a.class) {} // 继承 .a.class
all 关键字 #
使用 all 继承所有包含该选择器的规则:
less
.a.class {
color: red;
}
.a.class:hover {
color: blue;
}
.b:extend(.class all) {}
编译结果:
css
.a.class,
.b {
color: red;
}
.a.class:hover,
.b:hover {
color: blue;
}
继承嵌套选择器 #
less
.nav {
a {
color: blue;
&:hover {
color: red;
}
}
}
.sidebar-link:extend(.nav a) {}
编译结果:
css
.nav a,
.sidebar-link {
color: blue;
}
.nav a:hover,
.sidebar-link:hover {
color: red;
}
@extend vs Mixin #
使用 Mixin #
less
.message() {
color: #333;
padding: 10px;
border: 1px solid #ccc;
}
.success {
.message();
border-color: green;
}
.warning {
.message();
border-color: orange;
}
.error {
.message();
border-color: red;
}
编译结果:
css
.success {
color: #333;
padding: 10px;
border: 1px solid #ccc;
border-color: green;
}
.warning {
color: #333;
padding: 10px;
border: 1px solid #ccc;
border-color: orange;
}
.error {
color: #333;
padding: 10px;
border: 1px solid #ccc;
border-color: red;
}
使用 @extend #
less
.message {
color: #333;
padding: 10px;
border: 1px solid #ccc;
}
.success {
&:extend(.message);
border-color: green;
}
.warning {
&:extend(.message);
border-color: orange;
}
.error {
&:extend(.message);
border-color: red;
}
编译结果:
css
.message,
.success,
.warning,
.error {
color: #333;
padding: 10px;
border: 1px solid #ccc;
}
.success {
border-color: green;
}
.warning {
border-color: orange;
}
.error {
border-color: red;
}
对比总结 #
| 特性 | @extend | Mixin |
|---|---|---|
| CSS 输出量 | 较少(合并选择器) | 较多(复制样式) |
| 参数支持 | 不支持 | 支持 |
| 媒体查询 | 不能跨媒体查询 | 可以跨媒体查询 |
| 源码映射 | 不易追踪 | 易于追踪 |
| 使用场景 | 共享相同样式 | 需要参数化 |
媒体查询限制 #
@extend 不能跨媒体查询使用:
less
// 错误示例
.message {
color: red;
}
@media (min-width: 768px) {
.box:extend(.message) {} // 无效!
}
// 正确做法:使用 Mixin
.message() {
color: red;
}
.message {
.message();
}
@media (min-width: 768px) {
.box {
.message(); // 有效
}
}
实用示例 #
按钮变体 #
less
.btn {
display: inline-block;
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
transition: all 0.2s;
&:hover {
opacity: 0.9;
}
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
}
.btn-primary {
&:extend(.btn);
background: #007bff;
color: white;
}
.btn-secondary {
&:extend(.btn);
background: #6c757d;
color: white;
}
.btn-danger {
&:extend(.btn);
background: #dc3545;
color: white;
}
编译结果:
css
.btn,
.btn-primary,
.btn-secondary,
.btn-danger {
display: inline-block;
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
transition: all 0.2s;
}
.btn:hover,
.btn-primary:hover,
.btn-secondary:hover,
.btn-danger:hover {
opacity: 0.9;
}
.btn:disabled,
.btn-primary:disabled,
.btn-secondary:disabled,
.btn-danger:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.btn-primary {
background: #007bff;
color: white;
}
.btn-secondary {
background: #6c757d;
color: white;
}
.btn-danger {
background: #dc3545;
color: white;
}
表单输入 #
less
.form-control {
width: 100%;
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
&:focus {
border-color: #007bff;
outline: none;
}
}
.form-control-sm {
&:extend(.form-control);
padding: 4px 8px;
font-size: 12px;
}
.form-control-lg {
&:extend(.form-control);
padding: 12px 16px;
font-size: 18px;
}
清除浮动 #
less
.clearfix {
&::before,
&::after {
content: "";
display: table;
}
&::after {
clear: both;
}
}
.container {
&:extend(.clearfix);
max-width: 1200px;
margin: 0 auto;
}
.row {
&:extend(.clearfix);
margin: 0 -15px;
}
文本截断 #
less
.text-truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.card-title {
&:extend(.text-truncate);
font-size: 18px;
font-weight: bold;
}
.nav-item {
&:extend(.text-truncate);
padding: 8px 12px;
}
占位符选择器 #
Less 没有像 Sass 那样的占位符选择器(%),但可以使用 @import (reference) 实现类似效果:
less
// _base.less(使用 reference 导入)
.base-button {
display: inline-block;
padding: 8px 16px;
border-radius: 4px;
}
// main.less
@import (reference) "_base.less";
.my-button {
&:extend(.base-button);
background: #007bff;
}
编译结果:
css
.my-button {
display: inline-block;
padding: 8px 16px;
border-radius: 4px;
background: #007bff;
}
最佳实践 #
何时使用 @extend #
- 多个选择器共享完全相同的样式
- 需要减少 CSS 文件大小
- 样式关系是"is-a"关系(如:.error 是 .message)
何时使用 Mixin #
- 需要传递参数
- 样式需要在不同媒体查询中使用
- 需要更清晰的源码映射
避免过度继承 #
less
// 不推荐:继承链过长
.a { color: red; }
.b:extend(.a) { font-size: 12px; }
.c:extend(.b) { font-weight: bold; }
.d:extend(.c) { margin: 10px; }
// 推荐:直接继承基础类
.a { color: red; }
.b:extend(.a) { font-size: 12px; }
.c:extend(.a) { font-weight: bold; }
.d:extend(.a) { margin: 10px; }
组合使用 #
less
// 基础样式使用 @extend
// 可变样式使用 Mixin
.base-button() {
display: inline-block;
padding: 8px 16px;
border-radius: 4px;
}
.button-base {
.base-button();
}
.btn-primary {
&:extend(.button-base);
background: #007bff;
color: white;
}
.btn-secondary {
&:extend(.button-base);
background: #6c757d;
color: white;
}
下一步 #
现在你已经掌握了继承,接下来学习 循环 来生成重复样式!
最后更新:2026-03-28