Автоматическое создание стилей LESS для значков спрайтов

У меня есть изображение спрайтов значков с каждым значком в области 20 на 20 пикселей. Каждая иконка имеет несколько вариантов (черный, цветной, белый маленький и т.д.). И иметь их значительное количество. Вместо того, чтобы писать стили для каждого отдельного значка, я бы предпочел просто указать их имена в моем LESS-файле и позволить процессору сгенерировать для них стили.

Это то, что я придумал, но, похоже, это не работает.

@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);

Единственное, что я хотел бы изменить, это переменную @icons, где я просто ввожу их имена. И я использую надстройку Web Essentials для Visual Studio 2013, чтобы автоматически обрабатывать мой файл LESS при сохранении файла.

Что я делаю не так?


person Robert Koritnik    schedule 16.12.2013    source источник


Ответы (2)


Pure LESS (при условии, что вы используете Web Essentials 2013, который использует 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}
}

Я удалил & из имен селекторов, так как он не действует при создании этих классов в глобальной области видимости (но верните его, если вам действительно нужно, чтобы .iconize был вложен в другой набор правил). Также можно вычислить длину массива в более ранних версиях LESS (в которых нет функции length) без какого-либо javascript, но я не привожу здесь этот метод, так как он довольно страшный (и он вам все равно не нужен).


Ваш цикл на основе javascript на самом деле менее или более правильный, но проблема заключается в том, что все значения, возвращаемые встроенным javascript LESS, имеют тип так называемого «анонимного значения», а не числа, поэтому условие when (@c < @count) всегда истинно, и цикл становится бесконечным. (в основном условие расширяется точно так же, как when (0 < ~'9') ... when (9 < ~'9') = true и т. д.)

person seven-phases-max    schedule 16.12.2013
comment
Да, мои классы вложены друг в друга, поэтому мне нужно &. И спасибо за это решение, поскольку оно работает отлично, как я этого хочу. Мне кажется странным, что официальная документация LESS.org ничего не говорит о функциях length или extract. Может быть, есть лучший сайт документации? - person Robert Koritnik; 16.12.2013
comment
Да, лучшие документы находятся в разработке: github.com/less/less-docs (up -на сегодняшний день ссылка на функции) - person seven-phases-max; 16.12.2013
comment
@Robert Я обновил пример, добавив немного более умную обработку аргументов .iconize, чтобы вам не приходилось повторять length(@icons) каждый раз, когда используется .iconize. - person seven-phases-max; 16.12.2013
comment
Спасибо, но я все равно звоню только один раз. Однако было еще кое-что, что я изменил: вычисления фоновой позиции, поскольку @i находится между 1 и length(@icons). Я вычел из него 1, чтобы смещения были правильными. - person Robert Koritnik; 16.12.2013
comment
Ах, верно, я пропустил ту часть, основанную на 0 и основанную на 1... Так что я тоже обновлю пример... - person seven-phases-max; 16.12.2013

Я думаю, это зависит от версии LESS, которую вы используете. Различные версии LESS обрабатывают массивы как структуры и их длину.

Начиная с LESS 1.5 вы можете определить массив с кавычками, например:

@array: "value1","value2"; и вычислить его длину с помощью length(@array).

Например, см. также: Проблема с увеличением спрайтов LESS CSS Variable

С LESS 1.5 ваш код заканчивается бесконечным циклом: «SyntaxError: Максимальный размер стека вызовов превышен в»

person Bass Jobsen    schedule 16.12.2013