Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LESS CSS guards without mixin

Tags:

less

I'm just getting into LESS and am trying to figure out how I can make conditional css statements without mixins. I find that I have a lot of single line css statements that only occur once but are dependent on some variable or condition and that using mixins is a bit pointless since it will never be reused.

Example.

@add-margin: true;

body {
    margin-top: 20px;  //I only want this if add-margin is true
}

So ideally I want this:

body when (@add-margin) {
     margin-top: 20px;
}

But that doesn't work. Using a mixin works but seems silly to make one just for a one liner. Is there some alternative way I can do this?

Thanks

like image 976
cyberwombat Avatar asked Jul 02 '12 23:07

cyberwombat


People also ask

How do I make LESS mixin?

Mixins can be made to disappear in the output by simply placing the parentheses after it.

What is the difference between LESS and CSS?

CSS and LESS are not completely different, but LESS does offer additional features that make your projects easier. More than that, the compiled version of LESS is actual CSS. Feel free to share your feedback as comments to this blog.

What does the special variable @arguments do in a LESS mixin?

A guard is a special expression that is associated with a mixin declaration that is evaluated during the mixin process. It must evaluate to true before the mixin can be used. Guards are useful when you want to match on expressions, as opposed to simple values or arity.


3 Answers

yes you can, it's similar to your code.

@add-margin: true;

.margin() when (@add-margin) {
    margin-top: 20px;
}

body { .margin(); }

UPDATE: Using the latest versions of LESS (1.5+), usage of "guarded mixins" are not required to achieve this, and you could use "css gaurds" instead, therefore the OP's code will work out of the box

like image 163
Unicornist Avatar answered Sep 28 '22 07:09

Unicornist


CSS Guards feature was introduced in Less v1.5.0 and hence now we can use guards the same way as mentioned in the question.

@add-margin: true;

body when (@add-margin){
    margin-top: 20px;
}

If in case, you need to assign multiple such properties to different selectors based on the same variable, it can be implemented like below using the & selector.

& when (@add-margin){
    body{
        margin-top: 20px;
    }
    h1{
        margin-top: 10px;
    }
}

Note: As mentioned by memeLab in comments, any value for the @add-margin variable other than true are considered as falsy. This is because true is a keyword whereas 'true' is a String value. For example, the below would output nothing.

@add-margin: 'true';

body when (@add-margin){
    margin-top: 20px;
}

However, the below would work because it does a String comparison.

@add-margin: 'true';

body when (@add-margin = 'true'){
    margin-top: 20px;
}

If you are using Less compiler lower than v1.5.0 then the answer posted by Unicornist is the best bet.

like image 34
Harry Avatar answered Sep 28 '22 07:09

Harry


no, it is not possible in that form.

you could use a variable equal to 0 or 1 and multiply by 20 and then always output a rule, or use JavaScript (i would advise you to avoid this) to convert true to 0 or 20 and always output a rule, but if you want the property added conditionally, you need guards.

like image 27
Luke Page Avatar answered Sep 28 '22 06:09

Luke Page