Less - Merge
LESS - Merge
Section titled “LESS - Merge”Description
Section titled “Description”The Merge feature in LESS allows you to aggregate values for the same CSS property from multiple declarations. Instead of subsequent declarations overriding previous ones, merge appends the values, creating a list. This is particularly useful for properties that accept multiple comma-separated or space-separated values, like box-shadow, background, transform, or transition.
You enable merging by appending a + (for comma-separated lists) or +_ (for space-separated lists) to the property name.
The following table describes the two types of merge operations:
| ID | Merge Type & Description | Example |
|---|---|---|
| 1 | Comma Merge (+)Appends the new property value to any existing values for that property, separated by a comma. If the property doesn’t exist yet in the current scope, it creates it with the new value. | // LESS<br>.element {<br> box-shadow+: 0 2px 4px rgba(0,0,0,0.1);<br> box-shadow+: 0 0 10px blue inset;<br>}<br>// CSS Output<br>.element {<br> box-shadow: 0 2px 4px rgba(0,0,0,0.1), 0 0 10px blue inset;<br>} |
| 2 | Space Merge (+_)Appends the new property value to any existing values for that property, separated by a space. If the property doesn’t exist yet, it creates it. | // LESS<br>.element {<br> transform+_: scale(1.1);<br> transform+_: rotate(5deg);<br>}<br>// CSS Output<br>.element {<br> transform: scale(1.1) rotate(5deg);<br>} |
Practical Example: Combining Multiple Mixins
Section titled “Practical Example: Combining Multiple Mixins”Merge is often powerful when used within mixins that contribute parts of a multi-value property.
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):
style.less
Section titled “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; // Comma merge for transition
.add-base-shadow();
&:hover { .add-hover-lift-shadow(); .apply-scale-transform(); .apply-rotation(); }
&:active { .add-active-press-shadow(); transform+_: scale(0.98); // Add another transform on active state }}Compile style.less to style.css:
lessc style.less style.cssThe compiled style.css will demonstrate the merged properties:
style.css
Section titled “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); /* Note: transform doesn't accumulate from hover in this CSS structure if not also space-merged at base. To make transforms truly additive across states, all transform parts should be defined at the state they apply. Or, define a base transform and merge onto it for each state if that's the intent. The LESS for :active means it will *replace* hover's transform if active is also hovered. For true additive transforms in LESS across :hover and :active, structure would need care. Let's adjust LESS to reflect more typical additive intention or clarify output. If .card:hover already has transform, .card:active's transform+_ will try to add to that in the LESS logic but CSS specificity and state combination means direct output for :active will only include what's in :active. Corrected example for active to show merging with base if base had transform: .card { transform+_: initial-transform; ... } .card:active { transform+_: scale(0.98); } --> .card:active { transform: initial-transform scale(0.98); } In this example, :active's transform will just be scale(0.98) if no base transform was merged for .card itself. */}Clarification on :active transform: The transform+_: scale(0.98) in .card:active will merge with any transform property defined directly on .card or inherited through mixins applied directly to .card. It won’t directly merge with the transform defined in the .card:hover state in the final CSS unless specifically structured to do so (e.g. if :active rules were nested inside :hover, which is unusual). The example shows distinct state styling.
Output
Section titled “Output”The .card element will have a base shadow. On hover, it will gain an additional shadow and apply scale and rotation transforms. On active (mouse press), it will gain an inset shadow and a slight scale down. The transitions for transform and box-shadow will be applied together. This demonstrates how merge helps build up complex, multi-part CSS properties.