Sprites LESS CSS变量增量问题

时间:2013-11-25 17:24:20

标签: css less

我在使用变量进行精灵背景位置计算时遇到问题:

我的代码看起来像这样:

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

问题是@counter增量无法正常工作,如果我们替换,所有图标都显示为精灵图像中的第二个图标:

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

计数器的值正确显示...任何想法如何正确递增全局值? 谢谢(PS:我用的少了1.4.2)

2 个答案:

答案 0 :(得分:3)

严格说话你不能

LESS中的变量本质上是在特定范围内定义的常量,因此无法更改(包括递增)。因此,@counter: @index + 1;根本不会递增全局变量,而是在@counter的特定调用内为本地范围.myIconX()变量创建新值。 See the documentation on how variables work in LESS

通过递归局部变量设置模拟

这是有效的,基于被视为bug here的信息,但我不认为严格来说是一个错误。无论如何,它可以用来满足你的需求(我只是实现了@row: 1并调整了一些代码以显示计算工作):

@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是:

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

这表明,每次调用.myIconX() mixin时,都会按+1设置计数器以进行下一次调用。

警告:此解决方案是否基于错误行为是值得怀疑的,但如果是错误,此解决方案将来可能会消失。有关此方法的限制的进一步评论,see the discussion here

答案 1 :(得分:1)

由于基于计数器的解决方案似乎仍然可能有一些缺点取决于可能的用例(除了基于黑客的计数器本身,请参阅我的comment到相应的答案)我决定发布一个列表/我之前提到的基于循环的解决方案。 我将代码保存在尽可能接近基于计数器的代码中,以便可以轻松地进行比较。 (但总的来说,通过重命名和重新排序所有这些名称空间/选择器/ mixins /变量,删除不必要的引号等,可以使所有内容更加干净,结构化和通用,并进一步抛光。)

选项。 1

当您只需要精灵的任意图标以使其CSS输出中的类时:

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

选项。 2

当您只需要为精灵中的所有图标生成相应的类时:

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

P.S。这一切都是针对LESS 1.5.x的,我懒得让它与早期版本兼容 - 抱歉。