0

I have a LESS loop that generates different CSS (incremental) classes extracting color values from a list.

My current LESS code is the following:

.generate-detached(#f00, #0f0, #00f);

.generate-detached(@colors...) 
{
    .generate-detached-loop(1, @colors);
}

.generate-detached-loop(@i; @colors) when (@i <= length(@colors)) {
    @color: extract(@colors, @i);

    .detached-@{i} 
    {
        box-shadow: inset 0px 0px 8px 2px @color;

        > .toolbar > .drag-controls_container > .drag-control:before
        {
            box-shadow: inset 0px 0px 5px 1px @color;
        }
    }

    .generate-detached-loop((@i + 1), @colors);
}

The resulting CSS code is:

.detached-1 {
    box-shadow: inset 0px 0px 8px 2px #f00;
}
.detached-1 > .toolbar > .drag-controls_container > .drag-control:before {
    box-shadow: inset 0px 0px 5px 1px #f00;
}
.detached-2 {
    box-shadow: inset 0px 0px 8px 2px #0f0;
}
.detached-2 > .toolbar > .drag-controls_container > .drag-control:before {
    box-shadow: inset 0px 0px 5px 1px #0f0;
}
.detached-3 {
    box-shadow: inset 0px 0px 8px 2px #00f;
}
.detached-3 > .toolbar > .drag-controls_container > .drag-control:before {
    box-shadow: inset 0px 0px 5px 1px #00f;
}

Maybe I'm using old LESS constructs and actually exist some new techniques or in general... have you any idea to improve solution?

Chris Barr
  • 29,851
  • 23
  • 95
  • 135
Luca Detomi
  • 5,564
  • 7
  • 52
  • 77
  • What problem are you trying to solve? Are you just asking if this is a good solution? – Chris Barr May 15 '19 at 12:42
  • I know that is running correctly, but it's a quite verbose and a little unreadable. I thought that maybe there could be some new features in last version of LESS that could let to achieve same results with a more compact code or more intuitive (an example could be new `if()` statement instead of old `when()` guards) – Luca Detomi May 15 '19 at 12:44
  • *an example could be new if() statement instead of old when() guards* - If you mean the `if` function in Less v3 is not a replacement for `when` guards. – seven-phases-max May 15 '19 at 21:58

1 Answers1

1

It's more about your knowledge and understanding of existing language features rather than about language features themselves.

I.e. even in Less v2 (you're probably using) it's difficult to justify the existence of 4 extra lines of the .generate-detached(@colors...) mixin you have there.

E.g. why not:

@detached-colors: #f00 #0f0 #00f;

.detached-loop(@i: length(@detached-colors)) when (@i > 0) {
    .detached-loop(@i - 1);
    .detached-@{i} {
        @c: extract(@detached-colors, @i);
        box-shadow: inset 0px 0px 8px 2px @c;
        > .toolbar > .drag-controls_container > .drag-control:before {
            box-shadow: inset 0px 0px 5px 1px @c;
        }
    }
} .detached-loop;

Or:

.make-detached(#f00 #0f0 #00f);
.make-detached(@colors, @i: length(@colors)) when (@i > 0) {
    .make-detached(@colors, @i - 1);
    .detached-@{i} {
        @c: extract(@colors, @i);
        box-shadow: inset 0px 0px 8px 2px @c;
        > .toolbar > .drag-controls_container > .drag-control:before {
            box-shadow: inset 0px 0px 5px 1px @c;
        }
    }
}

?


Less v3 has each function:

each(#f00 #0f0 #00f, {
    .detached-@{index} {
        box-shadow: inset 0px 0px 8px 2px @value;
        > .toolbar > .drag-controls_container > .drag-control:before {
            box-shadow: inset 0px 0px 5px 1px @value;
        }
    }
});

But the similar thing exists for Less v2 as a plugin:

.for-each(@c, @i in @l: #f00 #0f0 #00f) {
    .detached-@{i} {
        box-shadow: inset 0px 0px 8px 2px @c;
        > .toolbar > .drag-controls_container > .drag-control:before {
            box-shadow: inset 0px 0px 5px 1px @c;
        }
    }
}
seven-phases-max
  • 11,765
  • 1
  • 45
  • 57
  • I started from [https://stackoverflow.com/questions/28151864/less-loop-using-data-stored-in-an-array-or-something-similar](this similar question solution) to develop this code. Anyway, your first solution runs correctly but values are stored in a map? The second one has some errors because it prints also "colors" or "extract(colors)" (at least trying with [http://lesscss.org/less-preview/](less-preview)). The v3 version is very nice and compact, the only thing is that is not possible to separate loop definition from values declaration – Luca Detomi May 16 '19 at 09:58
  • I saw that is possible to change a little v3 each version declaring `@detached-colors:#f00 #0f0 #00f;` and then replace each definition with `each(@detached-colors, {` really not bad. Just a remaining question, how does it works definition of different values of `@detached-colors:#f00 #0f0 #00f;` ? I tried also to remove spaces and it continues to work, so it's not the presence of spaces that separate values... I don't understand what kind of construct it is and I am unable to find documentation about it in official one – Luca Detomi May 16 '19 at 10:17
  • As for `@detached-colors:#f00 #0f0 #00f;` - I intentionally did not used a variable (except the example #2) just because *you* did not in your snippet (thus `.generate-detached(#f00, #0f0, #00f);` -> `each(#f00 #0f0 #00f ...`). – seven-phases-max May 17 '19 at 17:54
  • 1
    `#f00 #0f0 #00f` -well, it *is* [space separated list](https://stackoverflow.com/a/21011089) of values (in general there's no critical difference between comma and space lists (not counting context depended conventions like func arg list and so on)). *I tried also to remove spaces and it continues to work* - don't rely on that - in this particular case spaces can be ommited only because `#` itself is a non-ambiguous separator (so the spaces are assumed automatically like in a compressed CSS) - but normally the space must be there (well, assuming you're about writing a human-readable code). – seven-phases-max May 17 '19 at 18:11