问题
I've created a .smartMargin()
mixin for LESS CSS to be used in responsive design LESS.
I'm sharing it here for the benefit of others and also because I'm curious if there's any way to make it more efficient.
Idea
The mixin is designed to be called from within another mixin that represents a responsive design breakpoint. The idea is that you may want to override top, left, bottom, right margins individually by overriding one or more margins in each successive breakpoint.
In main mixin I just want one parameter for @videoMargin
as opposed to @videoMarginLeft
, @videoMarginRight
etc so that's why I've called it 'smartMargin'.
Usage
In my main file I define a breakpoint like this, and then call this mixin several times:
.breakpoint(@width, @color, @labelsSize, @videoMargin)
{
video
{
.smartMargin(@videoMargin);
}
}
.breakPoint(10em, red, 3em, 1em auto 1em auto);
.breakPoint(10em, green, 3em, 2em unset unset unset);
.breakPoint(20em, blue, 3em, unset 3em unset unset);
Output css
So for a given value of @videoMargin
here's the output css generated
generated css
-------------
.smartMargin(3em); margin: 3em;
.smartMargin(3em 1em 2em 4em); margin: 3em 1em 2em 4em;
.smartMargin(3em unset unset unset); margin-top: 3em;
.smartMargin(3em unset unset 4em); margin-top: 3em;
margin-right: 3em;
Implementation
The mixin is as follows. It works well but it just seems a little clumsy in places and you need to provide either 4 or 1 parameters. If anybody can optimize this I'd be very interested to see.
.smartMargin(@margin) when (length(@margin) = 4)
{
._smartMargin() when (extract(@margin, 4) = unset), (extract(@margin, 3) = unset), (extract(@margin, 2) = unset), (extract(@margin, 1) = unset)
{
.marginComponent(@name, @value)
{
& when not (@value = unset)
{
@{name}: @value;
}
}
.marginComponent(margin-top, extract(@margin, 1));
.marginComponent(margin-right, extract(@margin, 2));
.marginComponent(margin-bottom, extract(@margin, 3));
.marginComponent(margin-left, extract(@margin, 4));
}
._smartMargin() when (default())
{
margin: @margin;
}
._smartMargin();
}
.smartMargin(@margin) when (default())
{
& when not (@margin = ~'') and not (@margin = unset)
{
margin: @margin;
}
}
回答1:
You could possibly rewrite it to something like:
.smartMargin(@margin) when (isem(@margin)),(isem(extract(@margin,1))) and (isem(extract(@margin,2))) and (isem(extract(@margin,3))) and (isem(extract(@margin,4))) {
margin: @margin;
}
.smartMargin(@margin) when (default()) and (4 = length(@margin)) {
@positions: top, right, bottom, left;
.setmargin(@position,@margin) when (isem(@margin)){
margin-@{position}: @margin;
}
.setmargins(@i:1) when (@i <= 4){
.setmargin(extract(@positions,@i);extract(@margin,@i));
.setmargins((@i + 1));
}
.setmargins();
}
But in the first place i don't think there is something wrong with your code. Personally is should consider the use of unset
. I think you should use the initial
keyword or even 0
in stead of unset
. This enables you to do the following:
.smartMargin(@margin){
margin: @margin;
}
.one{
.smartMargin(3em);
}
.two{
.smartMargin(3em 1em 2em 4em);
}
.three{
.smartMargin(3em 0 0 0);
}
.four{
.smartMargin(3em 0 0 4em);
}
Or consider to use Passing Rulesets to Mixins, than you can use something like that shown below:
.breakPoint(@width, @color, @labelsSize, @videoMargin)
{
video
{
@videoMargin();
}
}
.breakPoint(10em, red, 3em, {margin: 1em auto 1em auto;});
.breakPoint(10em, red, 3em, {margin: 1em auto;});
.breakPoint(10em, green, 3em, {margin: 2em 0 0 0;});
.breakPoint(10em, green, 3em, {margin: 2em 0 0;});
.breakPoint(10em, green, 3em, {margin-top: 2em;});
.breakPoint(20em, blue, 3em, {margin: 0 3em 0 0;});
.breakPoint(20em, blue, 3em, {margin-right: 3em;});
来源:https://stackoverflow.com/questions/24029771/smart-margin-mixin-for-less