9

With SASS you can create an array of variables like this:

$badge-colors: blue #7FB3D4, gray #767676, green #8CC079, red #b35d5d, dark-red #b5473e, black #666, cyan #81BABD, purple #AEA7CF;

Is there some way of creating arrays with Less as well?

seven-phases-max
  • 11,765
  • 1
  • 45
  • 57
William
  • 3,335
  • 9
  • 42
  • 74
  • 1
    Just change `$` to `@` and you get your less array. Also see corresponding LESS [functions](https://github.com/less/less-docs/blob/master/content/functions/list.md) – seven-phases-max Jan 06 '14 at 16:57
  • Perfect - the only issue is that Visual Studio detects the "blue" key as a color and thusly paints a little square next to it - is there a good way of getting around this? – William Jan 06 '14 at 17:02

3 Answers3

28

The answer to the question is "Yes, you can create and work with arrays in Less". An array (in CSS and thus Less realm it's usually referred to as "List") is defined with just the same code as in your Q:

@badge-colors: blue #7FB3D4, gray #767676, green #8CC079, red #b35d5d;
  • See "List Functions" for functions to help you to iterate through such lists/arrays and access their items.
  • Also see this answer for certain advanced/not-so-obvious properties of Less lists.
  • Additionally see the "Lists Plugin" for typical list/array/map manipulation functions and features.

A typical introductory example of working with Less arrays would be a snippet to iterate through simple color list (via loop) to create corresponding CSS classes:

@colors: blue, green, yellow, red;

// mixin to iterate over colors and create CSS class for each one
.make-color-classes(@i: length(@colors)) when (@i > 0) {
    .make-color-classes(@i - 1);
    @color: extract(@colors, @i); 
    .@{color} {
        color: @color;  
    }
}

.make-color-classes(); // run the mixin

The second example is a more practical version of the first one. Creating "custom color" classes from a "two-dimensional" list (in this case being a simple equivalent of a key/value array, i.e. "map") similar to the array of the question.

Using "Modern Less" (via less-plugin-lists .for-each statement):

@badge-colors: 
    blue  #44BBFF,
    gray  #F0F1F5,
    green #66CC99,
    red   #FC575E;

.for-each(@pair in @badge-colors) {
    @key: at(@pair, 1);
    .badge-@{key} {
        color: at(@pair, 2);
    }
}

Same example in "Legacy Less" (using recursive mixins):

// usage:

@badge-colors: blue #7FB3D4, gray #767676, green #8CC079, red #b35d5d;

.make-classes(badge, @badge-colors);

// impl.:

.make-classes(@prefix, @list) {
    .iter(length(@list));
    .iter(@i) when (@i > 0) {
        .iter(@i - 1);
        @pair:  extract(@list, @i); 
        @key:   extract(@pair, 1);
        @value: extract(@pair, 2); 
        .@{prefix}-@{key} {
            color: @value;  
        }
    }
}

And finally, for more specific array/list usage examples do not hesitate to start with basic queries here at SO:

Elista
  • 3
  • 4
seven-phases-max
  • 11,765
  • 1
  • 45
  • 57
  • 1
    (This answer is created solely to serve the purpose of pushing out rather overbloated and awful examples (for such a simple and minimalistic Q) of the previous answers). – seven-phases-max Jan 19 '16 at 01:30
  • Good job on this answer. Thanks! – styke Apr 07 '16 at 10:49
  • Could you please comment or explain how .iter works here? It looks like `.iter(length(@list))` sets up a function to hold the current iteration value. But I am a bit confused about that syntax using less. – Metropolis Feb 06 '17 at 19:36
  • @Metropolis `.iter(length(@list))` calls the mixin with starting index as parameter (and the mixin basically iterates from n (count of items in the list) to 0). For more details see the [Less documentation](http://lesscss.org) (and ["Loops"](http://lesscss.org/features/#loops-feature) in particular). – seven-phases-max Feb 06 '17 at 20:38
  • @seven-phases-max Thanks for the explanation. I understand the iteration part of this and understand what it does, but does that syntax just setup a blank mixin, which is then called below it? .make-classes is a mixin that accepts parameters and does something, but `.iter(length(@list))` seems like an empty mixin or something. I already have been over the less documentation a hundred times, and I would not be asking here if I found the answer there. – Metropolis Feb 06 '17 at 20:51
  • @Metropolis The statement is a mixin *call* (it does not *define* the mixin but *invokes* it). The syntax is not really different from function call/definition statements in mainstream languages (`foo(n);` is a call, `foo(n) {..}` is a definition) so I'm a bit wondering of your confusion. – seven-phases-max Feb 07 '17 at 06:46
  • Okay, I think maybe I have confused this. Re-reading what you said, "calls the mixin starting index as parameter", the question I am trying to ask is where is the mixin .iter? Is that built into less? Because I can not find documentation on .iter. – Metropolis Feb 07 '17 at 17:16
  • 1
    The mixin is defined right below the `.iter(length(@list));` line. `.iter(@i) {...}` - that's the one (see my prev. comment). – seven-phases-max Feb 07 '17 at 22:00
  • Ahhh....Thats it. I am used to having the call to it after the definition. Sorry for the dumb question, and thanks for the answer. – Metropolis Feb 14 '17 at 21:36
6
// DEFINE COLORS AS VARIABLES TO BETTER HANDLE
@blue: #7FB3D4;
@gray: #767676;
@green #8CC079;
@red #b35d5d;
@dark-red: #b5473e;
@black: #666;
@cyan: #81BABD;
@purple: #AEA7CF;

// CREATE ARRAY
@badge-colors: '@{blue}','@{gray}','@{green}','@{red}','@{dark-red}','@{black}','@{cyan}','@{purple}';
// SAVE YOUR ARRAY LENGTH
@howmany: length(@|badge-colors);

// LOOP THROUGH THEM, SEE: https://gist.github.com/juanbrujo
.loop (@index) when (@index > 0){
    // CLEAN EACH COLOR NAME
    @color: e(extract(@badge-colors, @index));
    // USE EACH COLOR
    element{
      color: @color;
    }
    .loop (@index - 1);
}
.loop(0){}
// KEEP LOOPING
.loop(@howmany);
// END
Jorge Epuñan
  • 710
  • 7
  • 9
-2
// DEFINE COLORS AS VARIABLES
@blue: #0000FF;
@green: #00FF00;
@red: #FF0000;
@yellow: #FFFF00;

// CREATE ARRAYS
@badge-color-names: 'blue', 'green', 'red', 'yellow';
@badge-colors: '@{blue}', '@{green}', '@{red}', '@{yellow}';

// MIXIN
.make-badge-colors(@badge-color-names, @badge-colors) {
  .badge-color(@index) when (@index =< length(@badge-colors)) {
    @name:  extract(@badge-color-names, @index);
    @value: extract(@badge-colors, @index);
    @item: ~".badge-@{name}";
    @{item} {
      color: color(@value) !important;
    }
    .badge-color(@index + 1);
  }
  .badge-color(1);
}

// CREATE
.make-badge-colors(@badge-color-names, @badge-colors);




// COMPILED OUTPUT
.badge-blue {
  color: #0000FF !important;
}
.badge-green {
  color: #00FF00 !important;
}
.badge-red {
  color: #FF0000 !important;
}
.badge-yellow {
  color: #FFFF00 !important;
}
Mohammad Dayeh
  • 299
  • 3
  • 7