Sprites LESS CSS Variable increment issue

I have a problem with calculating the initial position of sprites using a variable:

My code looks something like this:

@counter: 1; #my-icon-bundle { .my-icons () { #my-icon-bundle .myIconX("classX1", @counter); #my-icon-bundle .myIconX("classYY1", @counter); ... } .myIconX(@name, @index) { @nameText: ~" .my-icon-@ {name}"; @{nameText} { #my-icon-bundle .myIcon(@index); } @counter: @index + 1; } .myIcon(@row) { @x: some calculations based on @row @y: some calculations based on @row background-position: -@x -@y ; } } 

The problem is that the @counter increment is not working correctly and all the icons are displayed as the second icon in the sprite image if we replace:

 #my-icon-bundle .myIconX("classX1", @counter); 

when the counter value is displayed correctly ... any ideas on how to properly increase the global value? Thanks (PS: I use less than 1.4.2)

+2
css less
source share
2 answers

Strictly speaking, you cannot

Variables in LESS are essentially constants defined in a certain area, and therefore they cannot be changed (including increased). So your @counter: @index + 1; it does not increment the global variable at all, but creates a new value for the local variable @counter inside this particular .myIconX() call. See the documentation on how variables work in LESS .

Emulation using recursive local variable setting

This works based on information that is considered a mistake here, but I do not believe that, strictly speaking, a mistake. Anyway, it can be used to meet your needs (I just implemented @row: 1 and changed the code to show how the calculation works):

 @row: 1; .init() { .inc-impl(1); } .init(); .inc-impl(@new) { .redefine() { @counter: @new; } } #my-icon-bundle { .my-icons () { #my-icon-bundle .myIconX("classX1", @counter); #my-icon-bundle .myIconX("classYY1", @counter); } .myIconX(@name) { .redefine(); .inc-impl((@counter + 1)); @nameText: ~" .my-icon-@ {name}"; @{nameText} { #my-icon-bundle .myIcon(@row); } } .myIcon(@row) { @x: @row * @counter; @y: @row * @counter; background-position: -@x -@y ; } } #my-icon-bundle .myIconX("classX1"); #my-icon-bundle .myIconX("classX1"); #my-icon-bundle .myIconX("classYY1"); 

CSS output:

 .my-icon-classX1 { background-position: -1 -1; } .my-icon-classX1 { background-position: -2 -2; } .my-icon-classYY1 { background-position: -3 -3; } 

This demonstrates that with each call to mixin .myIconX() it sets the counter to +1 for the next call.

Warning: Whether this decision is based on erroneous behavior or not is questionable, but if it is a mistake, this decision may disappear in the future. For further comments on the limitations of this method, see the discussion here .

+3
source share

Since the counter-based solution seems to still have some drawbacks depending on the possible use cases (besides the thing based on the hack, see the comment for the corresponding answer) I decided to publish a solution based on a list / outline, about which I mentioned earlier. I keep the code here as close to the counter-based as possible so that they can be easily compared. (But in general, everything can be made very clean, structured and general, followed by polishing by renaming and reordering all these namespaces / selectors / mixins / variables, removing unnecessary quotes, etc.).

Opt. one

If you only need a custom sprite icon to have your class in CSS output:

 @row: 1; // ...... .my-icon-bundle { .myIcon(@row, @index) { @x: (@row * @index); @y: (@row * @index); background-position: -@x -@y ; } .myIconX(@name) { @icons: "classX1", "classYY1", "classZZZ", "anotheRR9", "etc."; .find(1); .find(@i) when (@name = extract(@icons, @i)) { @name_: e(@name); .my-icon-@ {name_} { #my-icon-bundle.myIcon(@row, @i); } } .find(@i) when not (@name = extract(@icons, @i)) { .find((@i + 1)); } } } // ...... // usage: #my-icon-bundle.myIconX("anotheRR9"); #my-icon-bundle.myIconX("classX1"); 

Opt. 2

When you just need to create the appropriate classes for all the icons in the sprite:

 @row: 1; // ...... #my-icon-bundle { .myIcon(@row, @index) { @x: (@row * @index); @y: (@row * @index); background-position: -@x -@y ; } .icons() { @icons: "classX1", "classYY1", "classZZZ", "anotheRR9", "etc."; .make(length(@icons)); .make(@i) when (@i > 0) { .make((@i - 1)); @name_: e(extract(@icons, @i)); .my-icon-@ {name_} { #my-icon-bundle.myIcon(@row, @i); } } } } // ...... // usage: #my-icon-bundle.icons(); 

PS All this for LESS 1.5.x, I'm too lazy to make it compatible with earlier versions - sorry.

+1
source share

All Articles