Skip to content

Less language Properties Merging

Mária Jurčovičová edited this page Feb 13, 2014 · 10 revisions

Values for transforms, backgrounds, shadows and other "combinable" css properties can be defined inside separate declarations and then merged together using either + or +_ placed after property name. If less ruleset contains multiple declarations of the same property followed by one of these operators, compiled css will have only one property declaration with all their values collected into one list.

List values retain order in which they appeared in compiled css and are separated either by comma or by space. The values whose property was marked by + are preceded by comma and the values marked with +_ are preceded by space.

Example - comma separated:

div { 
  box-shadow+: 40px 40px 5px #6f6f6f; // first light shadow
  box-shadow+: 40px 40px 5px #222222; // second darker shadow - will be separated by comma
}

compiles into:

div { // div has both shadows
  box-shadow: 10px 10px 5px #6f6f6f, 40px 40px 5px #222222;
}

Example - space separated:

div#spaces {
  transform+_: skew(30deg);
  transform+_: rotate(30deg);
  transform+_: translate(50px, 100px);
}

compiles into:

div#spaces {
  transform: skew(30deg) rotate(30deg) translate(50px, 100px);
}

Combinations

It is possible to combine + and +_ operator within one property:

div { 
  box-shadow+: 40px 40px; // first half of light shadow
  box-shadow+_: 5px #6f6f6f; // second half of light shadow - will be separated by space
  box-shadow+: 40px 40px; // first half of darker shadow - will be separated by comma
  box-shadow+_: 5px #222222; // second half of darker shadow - will be separated by space
}

compiles into:

div { // div has both shadows
  box-shadow: 10px 10px 5px #6f6f6f, 40px 40px 5px #222222;
}

Use Cases

Properties merging is used when developer wants to create mixins library and then combine mixins effects instead of overwriting them.

Add multiple shadows calculated by the same mixin:

// mixin adds parametrized shadow 
.add-shadow(@offset, @color) { 
  box-shadow+: @offset @offset 5px @color;
}
div { 
   // use mixin to add four shadows to the same element
  .add-shadow(10px, #6f6f6f); 
  .add-shadow(20px, #555555);
  .add-shadow(30px, #3c3c3c);
  .add-shadow(40px, #222222);
}

compiles into:

//div has all four shadows
div { 
  box-shadow: 10px 10px 5px #6f6f6f, 
              20px 20px 5px #555555, 
              30px 30px 5px #3c3c3c, 
              40px 40px 5px #222222;
}

Combine backgrounds and transformations:

//define mixins library
.rotate-and-skew() {
    transform+_: rotate(90deg), skew(30deg);
}
.longer-and-higher() {
    transform+_: scale(2,4);
}
.background-countryside() {
    background+: url(countryside.png);
}
.background-animals() {
    background+: url(animals.png);
}
//combine effects from multiple mixins
.some-selector {
    .rotate-and-skew();
    .longer-and-higher();
    .background-countryside();
    .background-animals();
}

combines into:

.some-selector {
  transform: rotate(90deg) skew(30deg) scale(2, 4);
  background: url(countryside.png), url(animals.png);
}

Important Keyword

Properties marked with !important keyword are merged separately from normal properties. Following:

.selector {
  transform+_: skew(30deg);
  transform+_: rotate(90deg);
  transform+_: scale(2,4) !important;
  transform+_: scale(3,3) !important;
}

compiles into:

.selector {
  transform: skew(30deg) rotate(90deg);
  transform: scale(2, 4) scale(3, 3) !important;
}

Positioning and Combinations

Only properties marked by + or +_ are merged together. Properties merging will not modify normal css declarations.

Following:

div { 
  background: url(clouds.png);
  background+: url(countryside.png);
  background+: url(animals.png);
  background: url(animals.png);
}

compiles into:

div {
  background: url(clouds.png);
  background: url(countryside.png), url(animals.png);
  background: url(animals.png);
}

Merged property takes the position of the first property it contains:

div { 
  transform: rotate(10deg);
  transform+_: rotate(20deg);
  transform: rotate(30deg);
  transform+_: rotate(40deg);
  transform: rotate(50deg);
}

compiles into:

div {
  transform: rotate(10deg);
  transform: rotate(20deg) rotate(40deg);
  transform: rotate(30deg);
  transform: rotate(50deg);
}