I have some LESS for making margins based on the side being passed (top, right, bottom, left or all):
.margin(@px,@side) when (@side = top) {
(){ margin-top: ~"@{px}px"; }
}
.margin(@px,@side) when (@side = right) {
(){ margin-right: ~"@{px}px"; }
}
.margin(@px,@side) when (@side = bottom) {
(){ margin-bottom: ~"@{px}px"; }
}
.margin(@px,@side) when (@side = left) {
(){ margin-left: ~"@{px}px"; }
}
.margin(@px,@side) when (@side = all) {
(){ margin-top: ~"@{px}px";
margin-right: ~"@{px}px";
margin-bottom: ~"@{px}px";
margin-left: ~"@{px}px"; }
}
My question is that if I have an ID like this:
#testfeature {
.margin(10px,l);
.margin(10px,r);
}
Then LESS compiles it like this:
#testfeature {
margin-left:10px;
}
#testfeature {
margin-right:10px;
}
How do I get it to compile like this:
#testfeature {
margin-left:10px;
margin-right:10px;
}
Get rid of the unnecessary () { ... }
's that are wrapping all of your mixin styles. They're causing the selectors to be interpreted oddly and separating them into different selections, rather than joining everything under one selection:
.margin(@px,@side) when (@side = top) {
margin-top: ~"@{px}px";
}
.margin(@px,@side) when (@side = right) {
margin-right: ~"@{px}px";
}
.margin(@px,@side) when (@side = bottom) {
margin-bottom: ~"@{px}px";
}
.margin(@px,@side) when (@side = left) {
margin-left: ~"@{px}px";
}
.margin(@px,@side) when (@side = all) {
margin-top: ~"@{px}px";
margin-right: ~"@{px}px";
margin-bottom: ~"@{px}px";
margin-left: ~"@{px}px";
}
You could probably also drop the ~"@{px}px"
in favor of simply @px
, also the last mixin should probably be:
.margin(@px, @side) when (@side = all) {
margin: @px;
}
To get them to "group" you need to create a nested and grouped mixin. Below is a grouped mixin function, "streamlined" for margin setting.
- It takes anywhere from 1 to 8 parameters; always in pairs of
position
then value
(except as noted below; it can accept any order of position and values of auto
or inherit
are allowed).
- Passing a single "position" just sets a
0px
margin on that position.
- Defaults non-unit numbers to
px
, but keeps explicitly set units as passed.
- Passing a single parameter that is number value will set all the margins to that number equally.
LESS Mixin
.setMargins(@s1: ~'', @v1: 0, @s2: ~'', @v2: 0, @s3: ~'', @v3: 0, @s4: ~'', @v4: 0) {
.setPos(top, @T) {
.setNum() when (isnumber(@T)) {
margin-top: @T * 1px;
}
.setNum() when not (isnumber(@T)){
margin-top: @T;
}
.setNum();
}
.setPos(right, @R) {
.setNum() when (isnumber(@R)) {
margin-right: @R * 1px;
}
.setNum() when not (isnumber(@R)) {
margin-right: @R;
}
.setNum();
}
.setPos(bottom, @B) {
.setNum() when (isnumber(@B)) {
margin-bottom: @B * 1px;
}
.setNum() when not(isnumber(@B)) {
margin-bottom: @B;
}
.setNum();
}
.setPos(left, @L) {
.setNum() when (isnumber(@L)) {
margin-left: @L * 1px;
}
.setNum() when not (isnumber(@L)) {
margin-left: @L;
}
.setNum();
}
//allows all to be called with one number or value
.setPos(@A, 0) when (isnumber(@A)) {
margin: @A * 1px;
}
.setPos(auto, 0) {
margin: auto;
}
.setPos(inherit, 0) {
margin: inherit;
}
//default null if no valid side given
.setPos(@other, 0) {}
//call all possible positions
.setPos(@s1, @v1);
.setPos(@s2, @v2);
.setPos(@s3, @v3);
.setPos(@s4, @v4);
}
Examples
.setMargins(right);
produces margin-right: 0px;
.setMargins(right, 15);
produces margin-right: 15px;
.setMargins(left, 10em);
produces margin-left: 10em;
.setMargins(top, 12, right, 10);
produces: margin-top: 12px; margin-right: 10px;
.setMargins(25);
produces: margin: 25px;
.setMargins(auto);
produces: margin: auto;
So you use it in a selector:
LESS
#testfeature {
.setMargins(left, 10, right, 10);
}
CSS Output
#testfeature {
margin-left: 10px;
margin-right: 10px;
}