Auto-generate LESS styles for sprite icons

ぃ、小莉子 提交于 2019-12-21 23:55:34

问题


I have icon sprites image with each icon in a 20 by 20 pixel area. Each icon has several variants (black, colour, white small etc.). And have a significant amount of them. Instead of writing styles for each individual icon I'd rather just provide their names in my LESS file and let the processor generate styles for them.

This is what I came up with but it doesn't seem to work.

@icons: upvote,downvote,comment,new,notify,search,popup,eye,cross;

@array: ~`(function(i){ return (i + "").replace(/[\[\] ]/gi, "").split(","); })("@{icons}")`;
@count: ~`(function(i){ return i.split(",").length; })("@{icons}")`;

.iconize (@c) when (@c < @count) {
    @val: ~`(function(a){ return a.replace(" ","").split(",")[0]; })("@{array}")`;
    @array: ~`(function(a){ a = a.replace(" ","").split(","); a.splice(0, 1); return a; })("@{array}")`;

    &.@{val} { background-position: (-20px * @c) 0; }
    &.color.@{val} { background-position: (-20px * @c) -20px; }
    &.white.@{val} { background-position: (-20px * @c) -40px; }

    .iconize(@c + 1);
}

.iconize(@c) when (@c = @count) {}

.iconize(0);

The only thing I'd like to edit is the @icons variable where I just enter their names. And I'm using Web Essentials addin for Visual Studio 2013 to automatically process my LESS file on file save.

What am I doing wrong?


回答1:


Pure LESS (assuming you're using Web Essentials 2013 which uses LESS 1.5.x):

@icons: upvote, downvote, comment, new, notify, search, popup, eye, cross;

.iconize();
.iconize(@i: length(@icons)) when (@i > 0) {
    .iconize((@i - 1)); 

    @value: extract(@icons, @i); // LESS arrays are 1-based
    .@{value}       {background-position: (-20px * (@i - 1)) 0}
    .color.@{value} {background-position: (-20px * (@i - 1)) -20px}
    .white.@{value} {background-position: (-20px * (@i - 1)) -40px}
}

I removed & from selector names since it has no effect when you generate these classes in the global scope (but put it back if you actually need .iconize to be nested in another ruleset). It is also possible to calculate array length in earlier LESS versions (that have no length function) w/o any javascript, but I don't list this method here since it's quite scary (and you don't need it anyway).


Your javascript based loop is in fact less or more correct but the problem is all values returned by LESS inline javascript are of so-called "anonymous value" type and not a numbers so that when (@c < @count) condition is always true and the loop becomes infinite. (basically the condition is expanded exactly as when (0 < ~'9') ... when (9 < ~'9') = true etc.)




回答2:


I think it depends on the version of LESS you use. Different versions of LESS handle array like structures and their length different.

Since LESS 1.5 you can define an array with quotes, like:

@array: "value1","value2"; and calculate its length with length(@array).

For example see also: Sprites LESS CSS Variable increment issue

With LESS 1.5 your code ends in an endless loop: "SyntaxError: Maximum call stack size exceeded in"



来源:https://stackoverflow.com/questions/20605832/auto-generate-less-styles-for-sprite-icons

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!