Mach3.laBlog

“LESS” – Alphabetical Advent Calendar 2013

この記事は賞味期限切れです。(更新から1年が経過しています)

“L” は LESS の “L”。

L

LESS

LESSSassStylus 等と並び称されるCSSのメタ言語です。 くだいて言うと、スタイルシートをもっと楽に効率よく書くために開発されたツールです。 三者の中では Sass が筆頭で使われていて、LESS と Stylus がそれに続く印象です。

私の知る限りでは、元々 LESS は Sass と同じく Ruby ベースで開発されていましたが、 並行して開発された LESS.js の方が主流となって JavaScript ベースで開発されるようになり、 現在に至っています。

LESS 記法の基本

上に挙げたメタ言語ではおそらくどれでも共通している機能ですが、

  • セレクタを入れ子に出来る
  • 変数が使える
  • ミックスイン(関数のようなもの)が使える

これらの機能を把握しておくだけで、スタイルシートのコーディングが効率化出来るでしょう。

// 変数
@color-black: #000;
@color-red: #c00; 

// ミックスイン
.mx-box (@bg-color: #eee, @radius: 10px){
    background-color: @bg-color;
    border-radius: @radius;
    padding: @radius;
}

// セレクタの入れ子
.container {
    .box {
        &.black {
            // ミックスインと変数の呼び出し
            .mx-box(@color-black, 8px);
        }
        &.red {
            .mx-box(@color-red, 8px);
        }
    }
}

上のコードを LESS でコンパイルすると、次のようなコードが出力されます。 (拙作ですが、LESStester.com を使ってオンラインで出力のテストが出来ます)

.container .box.black {
    background-color: #000;
    border-radius: 8px;
    padding: 8px;
}

.container .box.red {
    background-color: #c00;
    border-radius: 8px;
    padding: 8px;
}

残念ながら、この例のコードはあまりに短い為にメタ言語の魅力を十分に伝えきれません。 「単にCSSが長くなっただけじゃないか」と思われる方もいらっしゃるかもしれません。

しかし例えば、似たパーツのバリエーションを多数作らなければいけなかったり、 複雑な子孫関係を持ったセレクタを延々と書かなければならないスタイルシートでは、どうでしょうか。 また、スタイルシートを書いた人の思考は、どちらによりよく反映されるでしょうか。 共有して作業しやすいのは、どちらでしょうか。

コードの行数よりも、調整やメンテナンスの効率で大きな違いが出てくる未来が想像できます。

LESS の魅力

こうしたツールはやはりマジョリティに依りたくなるのが当然です。 機能面でも、歴史があって柔軟かつ多彩な Sass に叶わない部分は多くみられますが、 LESS にも優れている所は勿論あるのです。

JavaScript ベースであること

全て JavaScript で書かれている為、クライアントサイドで動かすことができます。 実際の開発ではコンパイル済みのCSSに差し替えた方が良いと思いますが、 少し何かを試したい場合などには便利ですね。

<link rel="stylesheet/less" href="style.less">
<script src="less.js"></script>

また、JavaScript ベースだということは、 近年流行にのっている Grunt との相性も良いという事です。

Grunt では Sass / LESS / Stylus 共にコンパイルするプラグインが公式に提供されています。 JSベースである LESS / Stylus は npm でプラグインをインストールすればすぐ使えるようになりますが、 Sass は別途 ruby と sass をインストールしておく必要があります。

また当然、Sass は外部コマンドを node.js から呼ばなければならないので、 どうしてもコンパイルの効率が落ちてしまいます。

CSS離れをしない記法であること

これが LESS を推したい一番の理由なのですが、LESS の記法は他の二者に比べると生のCSSにかなり近い形になっています。 例えば、基本的なミックスイン(関数のようなもの)を LESS で書くとこうなります。

.border-radius(@radius:10px) {
  -webkit-border-radius: @radius;
     -moz-border-radius: @radius;
          border-radius: @radius;
}
.box { .border-radius(20px); }

CSS でクラスを定義するのとあまり変わりませんね。

「CSS離れをしない」という事は反面、Sass が持つような 条件分岐やループなどの強力な機能を実装しないという事になりますが、 学習コストを抑えられるという点ではメリットになります。

CSSの素養のある方なら誰でもそのコードを理解する事ができ、使いこなすようになるのにさして時間を要しません。

Bootstrap は LESS ベースです

Twitter からリリースされている Bootstrap は LESS で開発されており、 プロジェクトに Bootstrap を組み込む際には単純にCSSを読み込む他に LESS ファイルを利用する方法があります。

必要なモジュールだけを読み込んだり、変数を書き換えて見た目を調整したりする事ができるほか、 便利なミックスインも多数提供されています。 LESS で設計する際の教材としてみても良いかもしれませんね。

(なお、Bootstrap の Sass 版はサードパーティで公開されている方がいます)

注目すべき LESS の機能

最近になって実装された機能や、おすすめしたい要素等を少しご紹介します。

ミックスイン

ごく基本的な機能ですが、先に紹介した通り LESS のミックスインは非常にシンプルな作りになっています。

.inline-block(){
    display: inline-block;
    *display: inline;
    *zoom: 1;
}
.test {
    .inline-block();
}

引数を受け取る為の “()” 以外は CSS のクラスと変わらない記法です。 さらに、通常の CSS クラスもミックスインとして使用する事ができます。

.inline-block { ... }
.test {
    .inline-block();
}

上の2つのコードの違いは “()” の有無ですが、 これが記述されていない場合は通常の CSS クラスとして認識され、それ自身もコンパイル時に出力されます。 “()” が記述されていた場合はミックスインとして解釈される為、CSS のコードには出力されません。

名前空間

LESS のミックスインは 名前空間 をサポートしています。 多階層のミックスインを定義し、“>” で辿る事で呼び出すことができます。

.font-size (){
    .large (){ font-size: 1.5em; }
    .normal (){ font-size: 1em; }
    .small (){ font-size: 0.8em; }
}
.test {
    .font-size > .large();
}

このコードは次のように出力されます。

.test{font-size:1.5em}

ミックスインの名前による衝突をさけたり、LESS ベースのフレームワークを作るときなどに便利そうです。

extend

LESS 1.4 からサポートされたこの機能は、 元々 Sass で実装されていた extend を便利に感じた @hokaccha 氏が プルリクエストを送ったのが発端になったのだと思われます。 長いディスカッションの末、次のような形に落ち着いた模様です。

.box {
    background-color: #eee;
    border-radius: .5em;
    padding: 1em;
}
.foo {
    &:extend(.box);
    color: #333;
}
.bar {
    &:extend(.box);
    color: #00c;
}

&:extend( selector ) とする事で対象のスタイルを受け継ぐ事ができます。 普通のミックスインと違うのは出力の仕方です。 ミックスインの場合は “.box” の中身がそのままそこに展開されますが、 extend は巻き上げてグループ化して定義します。

上のコードは次のように出力されます。 最終的なコード量がかなり節約されますね。

.box,.foo,.bar{background-color:#eee;border-radius:.5em;padding:1em}
.foo{color:#333}
.bar{color:#00c}

多彩なインポート

外部 CSS をインポートする @import ですが、LESS では書き方によって特別な働きをします。

  • “*.css” をインポートすると @import 文のまま残す
  • “*.less” をインポートすると、LESS で展開した結果をインポートする
  • “*.less” の場合は拡張子を省略する事ができる

これが基本的なルールですが、 1.4 から @import (less) “style.css” のように 明示的に展開させる事が出来るようになりました。 現在開発中の 1.5 からは (inline) も使えるようになるようです。

// @import 文がそのまま残ります
@import "style.css";

// LESS でコンパイルされた結果がその場に展開されます。
// 拡張子を省略した場合は補完されます。
@import "style.less";
@import "style";

// (1.4~) 明示的にless|cssファイルとして処理する
@import (less) "style.css";
@import (css) "style.css";

// (1.5~) CSSファイルをその場に展開します
@import (inline) "style.css";

参考資料

2014/1/10
Less の表記を LESS に統一しました。

コメント

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*