Set parametric mixin output as variable in LESS - less

How do i set a parametric mixin output to a variable?
Say i have this custom mixin with these parameters:
.gradient(#555, #333, #777);
I want this to be put into a variable so i can refer to this specific gradient throughout my code.
Wrapping it like this:
#mixin elGradient() {
#include .gradient(#555, #333, #777);
}
for inclusion like this:
.element {
#include elGradient;
}
Yields a parse error.

.elGradient() {
.gradient(#555, #333, #777);
}
.element {
.elGradient();
}
This is the simplest way. Alternatively it would make sense to get use of the extend feature if you really need to include same properties again and again:
.elGradientBase {.gradient(#555, #333, #777)}
.elGradient() {
&:extend(.elGradientBase all);
}
.element-1 {
.elGradient();
}
.element-2 {
.elGradient();
}
// etc.

Related

Adding phasers to Block variables

On the trail of this question by Codesections, I'm trying to add a phaser to a variable using traits. Something like this:
my &doing-good is Block will enter {
.add_phaser: "ENTER",
{
if Backtrace.new.grep: { .subname ~~ /bad/ } {
fail("Not authorized to call this");
}
}
};
This fails with is trait on &-sigil variable not yet implemented. Sorry.
I arrived to this because there seems no way to declare that as a block; by default is a Callable, and add_method does not work on Callables, apparently. Any other way of doing this?

how to generate css (like .E.F) using less.js compiler

I would like to generate CSS using less compiler..
Originally I have a less file and I need to prepend every rule with some class (not a nested selector)
.E{ .F{ color:blue; } }
is going to generate
.E .F{color:blue;}
In my case I don't want it to be nested but should get generated in the following way
.E.F{color:blue;}
.E {
&.F { color:blue; }
}

Override global variables from within a mixin function

So I am trying to override some "global" variables based on a variable passed in from the php-less compiler.
I'm not sure if I am doing something wrong, or if it is just not possible due to the scope?
EDIT: I'm trying to get the background of the body to be red in this case.
external.less
// From external less stylesheet that I can't/don't want to modify
#myColour: blue;
body {
background: #myColour; // always blue
}
my.less
#import "external.less"
// My styles
.setResponsive(#responsive) when (#responsive = on) {
#myColour: green;
}
.setResponsive(#responsive) when (#responsive = off) {
#myColour: red;
}
#responsiveState: off; // actually being set from compiler
.setResponsive(#responsiveState);
div {
.setResponsive(#responsiveState);
background: #myColour; // red
}
http://codepen.io/anon/pen/gbOymJ
You are using the Mixins as Functions:
Variable defined directly in callers scope can not be overriden.
In your situation both #myColour: blue; and .setResponsive(#responsiveState); are in the same scope (the main scope). So what you are trying is not possible.
You should re-declare all the variables at the end of your code (using the same mechanism your are using to set #responsiveState )

Is there a way in LESS to remove a property if a variable does not exist?

Lets say I have a LESS file like this...
#myVariable: 5px;
.myRule {
myProperty1: #myVariable;
myProperty2: myOtherValue1;
}
I'll get this outcome when I compile this with LESS.
.myRule {
myProperty1: 5px;
myProperty2: myOtherValue1;
}
However, instead of having #myVariable defined inside this LESS file, I want to reference it from somewhere else. My referenced file, may or may not contain this variable. Currently, if the variable is missing, I'll get a result like this.
.myRule {
myProperty1: ;
myProperty2: myOtherValue1;
}
Is there any LESS functionality that would allow me to remove the property completely if the variable was not provided so that my output was like this.
.myRule {
myProperty2: myOtherValue1;
}
I've looked through the language features of LESS and couldn't find anything that does this. Maybe I'm missing something?
This would be the syntax that I'm imagining, but I'm pretty sure this doesn't exist.
.myRule {
when(exists(#myVariable)) {
myProperty1: #myVariable;
}
myProperty2: myOtherValue1;
}
Set Default and Override
//Load in a master variable file for all LESS
//containing all "possible" variables that may be used
//but set to some default values that "hide" the properties
//if the variable does not exist (such as "false" here)
#myVariable: false;
//Load in your specific variable references from elsewhere
//Individual variable may/may not be defined in this file
//but if one is defiend, this value overrides the previous value
#myVariable: 5px;
//Define a mixin to activate the setting of the property
//only if the value is not the original default hiding value
.setIfValue(myVariable) when not (#myVariable = false) {
myProperty1: #myVariable;
}
//Use the mixin to conditionally set the value into other mixins
.myRule {
.setIfValue(myVariable);
myProperty2: myOtherValue1;
}
Default Output
.myRule {
myProperty2: myOtherValue1;
}
Overridden Output
.myRule {
myProperty1: 5px;
myProperty2: myOtherValue1;
}
I think you made the syntax too complex. It should be something like this:
.myRule {
& when (#myVariable = false) {
myProperty1: #myVariable;
}
myProperty2: myOtherValue1;
}
This feature (apparently) is called CSS Guards.
It seems like you can check if a variable has a specific value, but not whether this allows you to check for defined or not.
So, I guess the other file should always define this variable as a prerequisite, but it can set it to 'false' (or any kind of default) to indicate that this property should not be used at all.

How to access variable created in my less bundle?

I have a less bundle like that :
#bundle-form {
#inputHeight: 30px;
.initForm(#borderColor, #borderHoverColor) { ... }
}
I can easily access to my function .initForm using the following code :
#bundle-form > .initForm(#grayLight, #grayDark);
But how to access to my #inputHeight variable ?
#bundle-form > #inputHeight; // Does not work !!!
Thanks !!
In short, no, you can't access namespace variables this way.
The only available method for the moment is to expand all entities of a particular namespace into current scope, e.g.:
#namespace {
#variable: 42px;
.mixin(#a, #b) {
// ...
}
}
.usage {
#namespace; // using "#namespace" namespace here
.mixin(1, 2); // OK
width: #variable; // OK
}