Dynamic class names in LESS
Solution 1
I don't think you're far off. What I've done is create a second variable inside the mixin, called @index2
. All this does is find the '920px minus @index' value that you're looking for:
@index2 = (920-@index);
this is then appended to the class name:
(~".gs@{index}-@{index2}") {
This is the complete loop:
.loopingClass (@index) when (@index > 160) {
@index2 = (920-@index);
// create the actual css selector, example will result in
// .myclass_30, .myclass_28, .... , .myclass_1
(~".gs@{index}-@{index2}") {
// your resulting css
width: (@index/20+1)*@col;
}
// next iteration
.loopingClass(@index - 60);
}
// "call" the loopingClass the first time with highest value
.loopingClass (@iterations);
In order to get just the set you are looking for (gs220-700 to gs700-220), just change @iterations
to equal 700.
Worth noting that currently, this will create the classes in the reverse order of how you specified them in the question.
Solution 2
This whole question was very helpful to me. I just wanted to post the solution to my problem as the way to do it has changed since LESS v 1.4
. LESS Changelog
Rather than using the ~
sign, you just write out the portion of the name that you want along with the normal @
and variable name with {}
surrounding it. So: #class@{variable}
.
For example, my solution using the same sort of loop became such:
/*Total number of passport inserts*/
@numInserts: 5;
/*Total width of the passport foldouts*/
@passportWidth: 300px;
/*Change in passport insert width per iteration*/
@passportWidthDiff: (@passportWidth / @numInserts);
/*"Array" of colors to select from to apply to the id*/
@passportColors:
blue orange green red yellow
purple white teal violet indigo;
/*The faux loop the doesn't end up in the final css
@index is the counter
@numInserts is the total number of loops*/
.loopingClass (@index) when (@index <= @numInserts){
/*This is the created ID with the index appended to it
You can also do this with classes such as if
we had had ".insert@{index}"*/
#insert@{index}{
/*Here are our properties that get adjusted with the index*/
width: (@passportWidth - (@passportWidthDiff * (@numInserts - @index)));
height: 50px;
background-color: extract(@passportColors, @index);
z-index: (@numInserts - @index);
}
/*Here we increment our loop*/
.loopingClass(@index + 1);
}
/*This calls the loop and starts it, I started from 1
since I didn't want to lead a className starting from 0,
But there is no real reason not to. Just remember to
Change your conditional from "<=" to "<"*/
.loopingClass(1);
And produces the following:
#insert1 {
width: 60px;
height: 50px;
background-color: #0000ff;
z-index: 4;
}
#insert2 {
width: 120px;
height: 50px;
background-color: #ffa500;
z-index: 3;
}
#insert3 {
width: 180px;
height: 50px;
background-color: #008000;
z-index: 2;
}
...
R Reveley
Bristol based user experience/web designer since 2001 who often ends up picking up code too.
Updated on June 09, 2022Comments
-
R Reveley about 2 years
I have the following bit of LESS code working
@iterations: 940; @iterations: 940; @col:2.0833333333333333333333333333333%; // helper class, will never show up in resulting css // will be called as long the index is above 0 .loopingClass (@index) when (@index > -20) { // create the actual css selector, example will result in // .myclass_30, .myclass_28, .... , .myclass_1 (~".gs@{index}") { // your resulting css width: (@index/20+1)*@col; } // next iteration .loopingClass(@index - 60); } // end the loop when index is 0 .loopingClass (-20) {} // "call" the loopingClass the first time with highest value .loopingClass (@iterations);
It outputs our grid system as so:
.gs940 { width: 100%; } .gs880 { width: 93.75%; } .gs820 { width: 87.5%; } .gs760 { width: 81.25%; } .gs700 { width: 75%; }
etc etc etc
Now what I want to do is some math to the class names to produce the following classes
.gs220-700 .gs280-640 .gs340-580 .gs400-520 .gs460-460 .gs520-400 .gs580-340 .gs640-280 .gs700-220
etc etc etc
basically this would be .(@index) - (920px minus @index)
But I have no idea if this is possible.
-
Michael Cordingley over 9 yearsI'm curious as to how this would look if we try to pull the repetitive properties out into a single block. In this case, the output that I'm talking about would look like this: #insert1, #insert2, #insert3 { height: 50px; }