Loop over an array of name value pairs in LESS

2019-01-04 12:44发布

Is there some way to loop an array of name/value pairs LESS? Something like this:

arr = alice: black, bob: orange;

.for(arr) // something something //
   .cl-@{name} {
       background-color: @{value}
   }

To generate something like this:

.cl-alice { background-color: black; }
.cl-bob { background-color: orange; }

I know that you can for-loop an array, but I'm unsure if it can be an array of objects rather than values in LESS.

标签: less
4条回答
相关推荐>>
2楼-- · 2019-01-04 13:18

The answer given by @seven-phases-max works very well. For completeness you should also notice that you can do the same in Less without the imported "for" snippet.

from lesscss.org

In trying to stay as close as possible to the declarative nature of CSS, Less has opted to implement conditional execution via guarded mixins instead of if/else statements, in the vein of @media query feature specifications.

and

In Less a mixin can call itself. Such recursive mixins, when combined with Guard Expressions and Pattern Matching, can be used to create various iterative/loop structures.

So in Less you could write:

@array: alice black, bob orange;

.createcolorclasses(@iterator:1) when(@iterator <= length(@array)) {
    @name: extract(extract(@array, @iterator),1);
    .cl-@{name} {
        background-color: extract(extract(@array, @iterator),2);
    }
    .createcolorclasses(@iterator + 1);
}
.createcolorclasses();

or indeed:

@array: alice black, bob orange;

.createcolorclasses(@iterator:1) when(@iterator <= length(@array)) {
    @name: extract(extract(@array, @iterator),1);
    &@{name} {
        background-color: extract(extract(@array, @iterator),2);
    }
    .createcolorclasses(@iterator + 1);
}
.cl-{
    .createcolorclasses();
}
查看更多
叛逆
3楼-- · 2019-01-04 13:21

In Less a "pair" (in its simplest form) can be represented as an array too, so it can be as simple as:

@import "for";

@array: alice black, bob orange;

.for(@array); .-each(@value) {
    @name:  extract(@value, 1);
    @color: extract(@value, 2);
    .cl-@{name} {
        background-color: @color;
    }
}

Note however that the ".for" thing is limited to the only loop per scope so it's better to rewrite above to something like this:

@import "for";

@array: alice black, bob orange;

.cl- {
    .for(@array); .-each(@value) {
        @name:  extract(@value, 1);
        &@{name} {
            background-color: extract(@value, 2);
        }
    }
}

The imported "for" snippet (it's just a wrapper mixin for recursive Less loops) can be found here (with examples here and here).

查看更多
萌系小妹纸
4楼-- · 2019-01-04 13:25

While it is useful from the other answers to know that Less supports recursive functions and mixins, there is now a much simpler answer to this simple question. This solution is tested to work with Less v3.9, but should work back to Less v3.7 when each was introduced.

.array() {
  alice: black;
  bob: orange;
}

each(.array(), {
  .cl-@{key} {
    background-color: @value;
  }
});

The output is tidy:

.cl-alice {
  background-color: black;
}

.cl-bob {
  background-color: orange;
}

Want more? Well, as they say, "You can haz more". Use @index to use the 1-based index in the formula above.

查看更多
来,给爷笑一个
5楼-- · 2019-01-04 13:45

Here is one "parametric mixins" which you can use with "key:value" pairs.

Array of "key:value" pairs is defined as follows: @array: "key:value", "key:value";

// imported "for" snippet (it's just a wrapper mixin for recursive Less loops)
// http://is.gd/T8YTOR
@import "for";

// loop all items and generate CSS
.generate_all(@array) {
    .for(@array);
    .-each(@item) {
        @name: e(replace(@item, ':(.*)', ''));
        @value: replace(@item, '^[^:]*:', '');
        @{name} {
            z-index: e(@value);
        }
    }
}

Definition:

@array_test: ".test:9000", "header .mainNav:9000", "footer:8000", "li.myclass:5000";

Test

.generate_all(@array);

Result:

.test {
  z-index: 9000;
}
header .mainNav {
  z-index: 8000;
}
footer {
  z-index: 7000;
}
li.myclass {
  z-index: 5000;
}

It works for me using grunt + less@1.7.4

查看更多
登录 后发表回答