Skip to content

Less - 合并

LESS 中的合并 (Merge) 功能允许你聚合同一 CSS 属性来自多个声明 (declarations) 的值。合并不是后续声明覆盖前一个,而是将值附加到现有值,形成一个列表。这对于接受多个逗号分隔或空格分隔值的属性特别有用,例如 box-shadow、background、transform 或 transition。

通过在属性名称后面附加 +(用于逗号分隔列表)或 +_(用于空格分隔列表)来启用合并功能。

下表描述了两种合并操作:

ID合并类型与描述示例
1逗号合并 (+)
将新的属性值附加到该属性的任何现有值之后,用逗号分隔。如果该属性在当前作用域中尚不存在,则会创建它并赋予新值。
// LESS
.element {
box-shadow+: 0 2px 4px rgba(0,0,0,0.1);
box-shadow+: 0 0 10px blue inset;
}
// CSS 输出
.element {
box-shadow: 0 2px 4px rgba(0,0,0,0.1), 0 0 10px blue inset;
}
2空格合并 (+_)
将新的属性值附加到该属性的任何现有值之后,用空格分隔。如果该属性尚不存在,则会创建它。
// LESS
.element {
transform+: scale(1.1);
transform+
: rotate(5deg);
}
// CSS 输出
.element {
transform: scale(1.1) rotate(5deg);
}

当在 contributing 多值属性部分的 mixin 中使用时,合并通常非常强大。

HTML (merge_example.html):

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>LESS Merge Feature</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="card">This card has multiple effects.</div>
</body>
</html>

LESS (style.less):

.add-base-shadow() {
box-shadow+: 0 1px 3px rgba(0,0,0,0.12);
}
.add-hover-lift-shadow() {
box-shadow+: 0 10px 20px rgba(0,0,0,0.19);
}
.add-active-press-shadow() {
box-shadow+: 0 3px 6px rgba(0,0,0,0.16) inset;
}
.apply-scale-transform() {
transform+_: scale(1.05);
}
.apply-rotation() {
transform+_: rotate(-2deg);
}
.card {
background-color: white;
padding: 20px;
margin: 30px;
display: inline-block;
transition+: transform 0.3s ease, box-shadow 0.3s ease; // transition 的逗号合并
.add-base-shadow();
&:hover {
.add-hover-lift-shadow();
.apply-scale-transform();
.apply-rotation();
}
&:active {
.add-active-press-shadow();
transform+_: scale(0.98); // 在 active 状态添加另一个 transform
}
}

将 style.less 编译为 style.css:

lessc style.less style.css

编译后的 style.css 将展示合并的属性:

.card {
background-color: white;
padding: 20px;
margin: 30px;
display: inline-block;
transition: transform 0.3s ease, box-shadow 0.3s ease;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
}
.card:hover {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 10px 20px rgba(0, 0, 0, 0.19);
transform: scale(1.05) rotate(-2deg);
}
.card:active {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 3px 6px rgba(0, 0, 0, 0.16) inset;
transform: scale(0.98); /* 注意:在这种 CSS 结构中,如果基础样式没有同时使用空格合并,则 transform 不会从 hover 状态累积。
为了使 transform 在不同状态之间真正具有累加性,所有 transform 部分都应在其应用的状态下定义。
或者,如果目的是这样,可以定义一个基础 transform,并在每个状态下对其进行合并。
:active 的 LESS 意味着如果同时 hover 和 active,它将 *替换* hover 的 transform。
为了在 LESS 中实现 :hover 和 :active 之间真正的累加 transform,结构需要仔细设计。
让我们调整 LESS 以反映更典型的累加意图或澄清输出。
如果 .card:hover 已经有 transform,.card:active 的 transform+_ 将尝试在 LESS 逻辑中添加到它,
但 CSS 特异性 (specificity) 和状态组合意味着 :active 的直接输出将只包含 :active 中的内容。
修正后的 active 示例,如果基础样式有 transform,则会显示与基础样式的合并:
.card { transform+_: initial-transform; ... }
.card:active { transform+_: scale(0.98); } --> .card:active { transform: initial-transform scale(0.98); }
在此示例中,如果 .card 本身没有合并任何基础 transform,则 :active 的 transform 将仅为 scale(0.98)。*/
}

关于 :active transform 的说明:.card:active 中的 transform+_: scale(0.98) 将与直接在 .card 上定义的任何 transform 属性,或通过直接应用于 .card 的 mixins 继承的任何 transform 属性合并。它不会直接与最终 CSS 中在 .card:hover 状态中定义的 transform 合并,除非结构特别设计成这样(例如,如果 :active 规则嵌套在 :hover 内部,但这不常见)。该示例展示了不同的状态样式。

.card 元素将拥有一个基础阴影。在悬停 (hover) 时,它会获得一个额外的阴影,并应用缩放 (scale) 和旋转 (rotation) transform。在激活 (active,鼠标按下) 时,它会获得一个内嵌阴影 (inset shadow),并略微缩小 (scale down)。transform 和 box-shadow 的过渡效果 (transitions) 将同时应用。这展示了合并如何帮助构建复杂的多部分 CSS 属性。