Help us understand the problem. What is going on with this article?

LESSでループ処理を実装する方法

More than 5 years have passed since last update.

LESSでも連番でクラスを定義したいことってありますね。
共通部分を関数にして、手動で連番を列挙する方法があります。

less
.foo(@num) {
    (~".foo-@{num}") {
        // style...
    }
}

.foo(1);
.foo(2);
.foo(3);
// ...
.foo(99);
.foo(100);

ただ、これが数十行ともなると書くのも大変ですし、LESS自体の見通しも悪くなりますね。プログラミングをやったことがある人であれば、for などのループで回せないかと考えると思います。

しかし、LESSはループ構文をサポートしていません。なので、再帰関数とLESSのガード(when)を使ってループっぽいことをします。このトリックはTwitter Bootstrapで使われています。

less
.iterate(@i) when not (@i < 10) { } // ループを抜けるために必要
.iterate(@i) when (@i < 10) {
    (~".test@{i}") {
        width: @i;
    }

    .iterate(@i + 1); // 次のループへ
}

.iterate(0); // ループを実行

これをコンパイルすると、次の通りループした結果のCSSが生成されます。

.test0 {
  width: 0;
}
.test1 {
  width: 1;
}
.test2 {
  width: 2;
}
.test3 {
  width: 3;
}
.test4 {
  width: 4;
}
.test5 {
  width: 5;
}
.test6 {
  width: 6;
}
.test7 {
  width: 7;
}
.test8 {
  width: 8;
}
.test9 {
  width: 9;
}

ちなみに、上のLESSをPHPで表現するとしたら下記のようなコードになります。PHPにはガードがありませんが、if分岐でガードします。再帰はLESSと同じですね。

<?php
function iterate($i) {
    if ( $i < 10 ) { // ガード
        echo ".test{$i} { width: {$i} }\n";

        iterate($i + 1); // 再帰
    } else {
        return;
    }
}

iterate(1);

LESSでループを実装するとトリッキーなコードになるので、ループを多く書く必要がある場面では、SaSSなどの別のツールと組み合わせたほうがいいかもしれませんね。

suin
Qiita 4位/TypeScript入門書執筆中/TypeScripterのための座談会「YYTypeScript」主催/『実践ドメイン駆動設計』書籍邦訳レビュア/分報Slack考案/YYPHP主催/CodeIQマガジン執筆/株式会社クラフトマンソフトウェア創設/Web自動テスト「ShouldBee」の開発/TypeScript/DDD/OOP
https://yyts.connpass.com/
craftsman_software
「インフラの心配は、もうおしまい」 インフラ運用を自動化し、手作業を限りなくゼロにする会社
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away