Generating classes with a loop - css

I have a list of colors and I want to generate classes using these colors:
CSS
#color1: #b37974;
#color2: #ffa385;
#color3: #ff5500;
#color4: #b2682e;
This is the code i'm using:
Less
.loopingClass(#index) when (#index > 0) {
#ctype: "color#{index}";
.setClass(#color,#cindex) {
.btn-color-#{cindex} {
background-color:#{color} ;
}
}
.setClass(e(##ctype),#index);
.loopingClass(#index - 1);
};
.loopingClass(2);
When I try to compile the code with gulp, I receive "Unrecognised input" error. When I remove background-color: #{color} the error goes away. What is my mistake in this code?
Update:
The correct code is:
.loopingClass(#index) when (#index > 0) {
#ctype: "color#{index}";
.setClass(#color,#cindex) {
.btn-color-#{cindex} {
background-color:#color ;
}
}
.setClass(##ctype,#index);
.loopingClass(#index - 1);
};
.loopingClass(2);

As I already mentioned in comments above the error there is in e function (which does not make any sense there). The correct code would look like this:
#color1: #b37974;
#color2: #ffa385;
#color3: #ff5500;
#color4: #b2682e;
.loopingClass(#index) when (#index > 0) {
#ctype: "color#{index}";
.setClass(#color, #cindex) {
.btn-color-#{cindex} {
background-color: #color;
}
}
.setClass(##ctype, #index);
.loopingClass(#index - 1);
}
.loopingClass(2);
In fact all this can be simplified to just:
#color1: #b37974;
#color2: #ffa385;
#color3: #ff5500;
#color4: #b2682e;
.loopingClass(#index) when (#index > 0) {
.btn-color-#{index} {
#color: "color#{index}";
background-color: ##color;
}
.loopingClass(#index - 1);
}
.loopingClass(2);
More over the whole thing could be even more simple since you don't need to emulate arrays via "indexed variable names" because you can use array directly (unless you need to refer to those vars separately elsewhere):
#colors:
#b37974,
#ffa385,
#ff5500,
#b2682e;
.loopingClass(2);
.loopingClass(#index) when (#index > 0) {
.loopingClass(#index - 1);
.btn-color-#{index} {
background-color: extract(#colors, #index);
}
}
And finally (since I entered "optimizations never end" mode anyway), same thing with a bit of syntactic sugar:
#import "for";
#colors:
#b37974
#ffa385
#ff5500
#b2682e;
.btn-color- {
.for(#colors); .-each(#color) {
&#{i} {background-color: #color}
}
}
where imported for is thefor.

Related

Gaps in sass css output

I'm writing some sass to generate a set of icons based on a series of parameters. I have a function that analyses a set of variables and then returns a 'scenario' variable which in turn is used to filter the information taken from the nested map where everything is stored.
The code which retreives the information from the nested map is as follows:
#each $key-lv0, $lv0 in $icon-config {
#if($key-lv0 == $scenario) {
.icon{
#each $key-lv1, $lv1 in $lv0 {
#if type-of($lv1) != "map" {
#{$key-lv1}: $lv1;
}
#each $key-lv2, $lv2 in $lv1 {
#if type-of($lv2) != "map" {
.#{$key-lv1} {
#{$key-lv2}: $lv2;
}
}
#each $key-lv3, $lv3 in $lv2 {
#if($key-lv2 == "hover") {
.#{$key-lv1}:#{$key-lv2} {
#{$key-lv3}: $lv3;
}
} #else {
.#{$key-lv1} #{$key-lv2} {
#{$key-lv3}: $lv3;
}
}
}
}
}
}
}
}
... and this produces something along these lines:
.icon .icon-header {
background-color: #00a9f0;
}
.icon .icon-header:hover {
border-color: #040100;
}
... etc ...
... which is fine - repeated statements aside whicvh I'll deal with later.
The problem is the cap between ".icon" and ".icon-header". These classes will all be used in a single element and for the css to be interpretted correctly it needs to generate something like this:
.icon.icon-header {
background-color: #00a9f0;
}
.icon.icon-header:hover {
border-color: #040100;
}
I've tried bringing ".icon" down like so:
#if type-of($lv1) != "map" {
.icon#{$key-lv1}: $lv1;
}
and removing it from the top but sass rejects this with the following error:
Error: Properties are only allowed within rules, directives, mixin includes, or other properties.
It seems such a minor thing but it's nagging me and I can't seem to find an answer.

Sass each function is compiling with dollar sign in front of it

I'm trying to use an each loop in Sass but the css is compiling with the variable name instead of the content of the variable.
$green-1: #9ae200;
$green-2: #5ea600;
$color-list: green-1 green-2;
#each $single-color in $color-list {
&.#{$single-color} {
background-color: $single-color;
}
}
The output I am looking for is:
.green-1 {
background-color:#9ae200;
}
.green-2 {
background-color:#5ea600;
}
But the css is compiling as:
.green-1 {
background-color:green-1;
}
.green-2 {
background-color:green-2;
}
So to try to get the dollar sign in there I tried this:
#each $single-color in $color-list {
#function create-variable($variable){
#return "$" + $variable;
}
&.#{$single-color} {
background-color: create-variable($single-color);
}
}
But that compiled as:
.green-1 {
background-color:$green-1;
}
.green-2 {
background-color:$green-2;
}
Sass is not reading the variables for some reason and is taking them literally. Anyone know how to make this work?
You cannot create dynamic variable in sass. Instead you can achieve your desired result using map
example:
$green-1: #9ae200;
$green-2: #5ea600;
$color-map: (
green-1: $green-1,
green-2: $green-2,
);
.body{
#each $key,$value in $color-map {
&.#{$key} {
background-color: $value;
}
}
}

Pass mixin as mixin param in LESS

I have the the following mixin:
.image-ui-wave-pos (#num, #selected:0) when (#selected = 0) {
background-position: -(#image-ui-wave-width * #num) -28px;
}
I'd like to pass it to the following mixin as parameter:
.small-button (#pos-macro, #buttons, #i) when (#i > 0) {
#button: extract(#buttons, #i);
&.#{button} {
.pos-macro (#i);
}
.small-button(#pos-macro, #buttons, #i - 1);
}
as the parameter #pos-macro calling it like this:
.small-button (.image-ui-wave-pos, #wave-buttons);
But it doesn't compile. How to do so?

LESS - Create ID by looping through two variables

I am trying to create a loop that outputs all of the possible combinations between coordinates -2,-2 to 2,2. Is there any way to do this without creating multiple loops?
Desired Output
#p1x0,#p2x0,#p-1x0,#p-2x0,#p1x1,#p-1x-1,#p-1x1,#p1x-1,#p2x2,#p-2x-2,p2x-2,p-2x2,#p2x1,#p2x-1,#p1x2,#p1x-2,#p-2x1,#p-2x-1,#p-1x2,#p-1x-2,#p0x-1,#p0x-2,#p0x0,#p0x1,#p0x2{}
Current Attempt
#cube-side {
border:red;
}
.create-cubes(#n, #i: -2, #z: -2, #side-sum:#i + #z) when (#side-sum =< #n) {
& when (#i < #z) {
.create-cubes(#n, #i+1);
}
& when (#z < #i) {
.create-cubes(#n, #z+1);
}
#p#{i}x#{z}:extend(#cube-side) {}
}
.create-cubes(4);
Output
#cube-side,
#p-2x-2 {
border: red;
}
There's way to do this w/o any loops at all:
#cube-side {
border: red;
}
-2, -1, 0, 1, 2 {
#p&x&:extend(#cube-side) {}
}
Though for an arbitrary list of values just a nested loop is the simplest solution of course (see for example), e.g. (in "pure Less") something like:
.create-cubes(-2, 2);
.create-cubes(#min, #max) {
.i; .i(#i: #min) when (#i <= #max) {
.j; .i(#i + 1);
}
.j(#j: #min) when (#j <= #max) {
#p#{i}x#{j}:extend(#cube-side) {}
.j(#j + 1);
}
}

Passing QLabel as a parameter in Qt Creator gives error

I am trying to pass a QLabel as a parameter to another function that is supposed to change the style of the label:
main
{
...
setSeatColor(ui->lblPan2Seat5B, 2);
}
void setSeatColor(QLabel& lbl, int i)
{
if(i == 1)
{
lbl.setStyleSheet("QLabel { background-color : blue; color : white; }");
}
else if(i == 2)
{
lbl.setStyleSheet("QLabel { background-color : red; color : white; }");
}
else if(i == 3)
{
lbl.setStyleSheet("QLabel { background-color : green; color : white; }");
}
else
{
lbl.setStyleSheet("QLabel { background-color : rgb(240,240,240); color : back; }");
}
}
The error in the function:
"No matching function for call to setSeatColor(QLabel*&,int)"
Your help is much appreciated!
You pass a QLabel pointer to a function that takes a QLabel&, so replace this call:
setSeatColor(ui->lblPan2Seat5B, 2);
with this one (notice the dereference operator *)
setSeatColor(*ui->lblPan2Seat5B, 2);
//you can use extra parentheses for your colleagues, so that they can understand what are you doing there: setSeatColor( *(ui->lblPan2Seat5B), 2); - that way is a little clearer that you intend to dereference the lblPan2Seat5B not the ui that is dereferenced by the -> operator

Resources