Using LESSPHP, passing variables as arguments into Mixins - less

V: lessphp v0.3.4-2
Using this:
#topDarkGrey: #6e6c74;
#bottomDarkGrey: #5d5b64;
.gradient (#startColor: #eee, #endColor: white) {
background-color: #startColor;
background: -webkit-gradient(linear, left top, left bottom, from(#startColor), to(#endColor));
background: -webkit-linear-gradient(top, #startColor, #endColor);
background: -moz-linear-gradient(top, #startColor, #endColor);
background: -ms-linear-gradient(top, #startColor, #endColor);
background: -o-linear-gradient(top, #startColor, #endColor);
}
background: .gradient(#topDarkGrey, #bottomDarkGrey);
I receive:
lessphp fatal error: parse error: failed at `background: .gradient(#topDarkGrey, #bottomDarkGrey);
Anyone see any problems with this?

Yes, this:
background: .gradient(#topDarkGrey, #bottomDarkGrey);
Should be this:
.gradient(#topDarkGrey, #bottomDarkGrey);

Related

Conditional when in less-file

I am making a theme editor for WordPress, and would like to use less to build the CSS file.
I have put a string in a variable like this:
#banner-separation-style: 'thick_border';
Then I'm trying to use when() like this:
when (#banner-separation-style = 'thick_border') {
header {
... some style
}
... and some css selectors
}
I've also tried combinations without quoting the variable.
How do I properly create something similar to if-blocks with less?
Guards (when statement) can only be used along with a mixin or a CSS selector. We can't write a when statement without using one of those. So, either write it with a mixin like below:
#banner-separation-style: 'thick_border';
.border-styles() when (#banner-separation-style = 'thick_border') {
header { border: 2px solid red; }
nav { border: 2px solid green; }
}
.border-styles;
or directly with the CSS selector like below:
#banner-separation-style: 'thick_border';
header when (#banner-separation-style = 'thick_border') {
border: 2px solid red;
}
nav when (#banner-separation-style = 'thick_border') {
border: 2px solid green;
}
or atleast using an unnamed selector (&) like below:
#banner-separation-style: 'thick_border';
& when (#banner-separation-style = 'thick_border') {
header { border: 2px solid red; }
nav { border: 2px solid green; }
}
The first version (with mixin) is the one that I prefer because (a) you don't have to repeat the condition multiple times like in the CSS selector version and (b) giving the mixin a name makes it more readable than using an unnamed selector. It is just my choice and some other user could actually prefer the last because it doesn't need that extra mixin call statement.

How to Add in Less Meta Informations for a Mixin Class? (phpStorm)

Is it possible in Less to setup mixin informations that can read phpStorm?
I write a Mixin like this:
.action-btn(#size: 32px, #color: #fff, #bgColor: #overlayStyleBlack, #bgColorHover: #red) {
a {
width: #size;
display: block;
color: #color;
text-align: center;
line-height: #size;
background-color: #bgColor;
&:hover {
cursor: pointer;
background-color: #bgColorHover;
}
}
}
What i want now is, that when i use this mixin in another less file: ".action-btn();" then i want to see that i have in this Mixin 4 Settings that i can Setup. In php Classes i can do this with:
/**
* #param string $xxx
* function to check and change user is_online flag in sphinx and in mysql
*/
But this dont work in the Less Mixin File.
And how can i Skip some settings? Here a example to explain what i mean. (This ry dont worked)
.action-btn(64px, , , #fff);

LESSCSS: interpolation of a mixin argument

I have the following code:
#red_SOPRA: orange;
#red: red;
.gradient(#color) when (#color = red)
{
background: linear-gradient( 180deg, #color 0%,yellow 100%);
}
div
{
.gradient(red);
}
Compiled into:
div {
background: linear-gradient(180deg, #ff0000 0%, #ffff00 100%);
}
I would like to add "_SOPRA" to the end of variable "#color" present in background definition, in order to obtain an interpolated and dynamic name of variable used in mixin.
I tried with ## and #{color} definitions but without success.
How to obtain a generated background like this (with value "#ffa500" - #red_SOPRA value - instead of "#ff0000")?
div {
background: linear-gradient(180deg, #ffa500 0%, #ffff00 100%);
}
Option #1
Unless I'm missing something from what you are trying to achieve, then simply removing the guard expression when (#color = red) will get a "dynamic" value output for #color, allowing it to be called directly by #red_SOPRA or #blu_SOPRA (whatever you pass).
LESS
#red_SOPRA: orange;
#red: red;
.gradient(#color)
{
background: linear-gradient( 180deg, #color 0%, yellow 100%);
}
div {
.gradient(#red_SOPRA);
}
CSS Output
As you wanted...
div {
background: linear-gradient(180deg, #ffa500 0%, #ffff00 100%);
}
Option 2
You can set up the mixin to perform a "'merging' between string passed" and the "_SOPRA" suffix, something like this:
LESS
#red_SOPRA: orange;
#blu_SOPRA: blue;
.gradient(#pre; #SOPRA: ~'#{pre}_SOPRA'; #color: ##SOPRA)
{
background: linear-gradient( 180deg, #color 0%,yellow 100%);
}
div
{
.gradient('red');
}
.test {
.gradient('blu');
}
CSS Output
div {
background: linear-gradient(180deg, #ffa500 0%, #ffff00 100%);
}
.test {
background: linear-gradient(180deg, #0000ff 0%, #ffff00 100%);
}
This will not fail gracefully if #color does not resolve to a valid ##SOPRA value.
First of all, I would like to thank ScottS for his answer, especially second option that is what I needed.
Secondly, I add solution that finally yesterday I found by myself, very similar in philosophy but little different and (maybe) easier to understand by newby, due to a temp variable.
#red_SOPRA: orange;
#red: red;
.gradient(#color) when (#color = 'red')
{
#stop-1:~"#{color}_SOPRA";
background: linear-gradient( 180deg, ##stop-1 0%,yellow 100%);
}
div
{
.gradient('red');
}
Philosophy is the same, but with this "double passage" I think that could be more "talking"... :-)
UPDATE:
After correct comment of seven-phases-max, I updaded my solution. Please note that parameter must be passed as string with 'red'

linear gradient back ground not working in IE

i use http://www.colorzilla.com/gradient-editor to generate css codes for a linear gradient background
i got what i needed from the website and here's my code
div{
width:450px;;
height:250px;
background: -moz-linear-gradient(top, #eeeeee 50%, #cccccc 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(50%,#eeeeee), color-stop(100%,#cccccc)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #eeeeee 50%,#cccccc 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #eeeeee 50%,#cccccc 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #eeeeee 50%,#cccccc 100%); /* IE10+ */
background: linear-gradient(to bottom, #eeeeee 50%,#cccccc 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#cccccc',GradientType=0 ); /* IE6-9 */
}
the problem is it works for Chrome and i guess it will work for FF and most other browsers like Opera and Safari ..
the problem as always is, with IE (god cursed that bastard who invented IE and sent hem to hell)
even if i used filter: progid:DXImageTransform.Microsoft.gradient(My color rules) its not working
any suggestions folks ?
/* IE 7-*/ filter: progid:DXImageTransform.Microsoft.Gradient(startColorStr='#000000', endColorStr='#FFFFFF', GradientType=0);
/* IE 8+*/ -ms-filter: "progid:DXImageTransform.Microsoft.Gradient(startColorStr='#000000', endColorStr='#FFFFFF', GradientType=0)";
/* IE 10+ */ background-image: -ms-linear-gradient(top, #000000, #FFFFFF);

Generic `vendors` mixin

Defining vendors' mixins is common task under LESS, ie:
.box-shadow() {
-moz-box-shadow:#arguments;
-webkit-box-shadow:#arguments;
-o-box-shadow:#arguments;
-ms-box-shadow:#arguments;
box-shadow:#arguments;
}
.border-radius() {
-moz-border-radius:#arguments;
-webkit-border-radius:#arguments;
-o-border-radius:#arguments;
-ms-border-radius:#arguments;
border-radius:#arguments;
}
...
But it seems a bit repeating...
What I would like is a generic vendor mixin which do this for me, ie:
.vendors(#prop, #val) {
-moz-#prop:#val;
-webkit-#prop:#val;
-o-#prop:#val;
-ms-#prop:#val;
#prop:#val;
}
Then defining box-shadow mixin would as simple as:
.box-shadow() {
.vendors(box-shadow, #arguments);
}
The problem is my .vendors mixin does not compile...
I tried:
.vendors(#prop, #val) {
-moz-#prop: #val; /* Error */
~"-moz-#{prop}": #val; /* Error */
~`"-moz-#{prop}": #val; /* Error */
}
Do you have an idea on how to do this?
Cheers
Stylus has this, which is called Interpolation, eg:
vendor(prop, args)
-webkit-{prop} args
-moz-{prop} args
{prop} args
border-radius()
vendor('border-radius', arguments)
box-shadow()
vendor('box-shadow', arguments)
— Then,
button
border-radius 1px 2px / 3px 4px
yields to:
button {
-webkit-border-radius: 1px 2px / 3px 4px;
-moz-border-radius: 1px 2px / 3px 4px;
border-radius: 1px 2px / 3px 4px;
}
\o/
Another option, that I think is a little cleaner, would be do create a list of vendors and then iterate over that list to create the particular styles you want. Here's an example:
ALLVENDORS = webkit moz o ms w3c
vendors(prop, args)
for vendor in ALLVENDORS
if vendor == w3c
{prop}: args
else
-{vendor}-{prop}: args
This creates a list of vendors that you want to support and then allows you to reuse them. if later, you decide you want to support another prefix or want to remove one, all you have to do is remove it from the list.
And then you would use the list just as shown above:
border-radius()
vendors(border-radius, arguments)
box-shadow()
vendor(box-shadow, arguments)
I'm pretty sure less now has it. I've used this code in a Meteor.js project:
.vendor(#property, #value) {
-webkit-#{property}: #value;
-khtml-#{property}: #value;
-moz-#{property}: #value;
-ms-#{property}: #value;
-o-#{property}: #value;
#{property}: #value;
}
.vertical-align {
position: relative;
top: 50%;
.vendor(transformY, -25%);
}