はじめに
生のCSSだけでスタイルを書いていると、同じ色や余白の数値をあちこちにコピペして、後から一括で変えたくなった瞬間に絶望する、という経験は誰しもあるはずです。CSSカスタムプロパティ(--colorのような変数)が使えるようになった今でも、ネストや演算、条件分岐まで含めて「プログラムのようにCSSを書く」となると、まだプリプロセッサの出番があります。
その代表格がSassですが、実はSassより前からCSSに変数とネストを持ち込んでいたのがLessです。しかもLessは、Node.jsのビルドツールとしてだけでなく、ブラウザ上のJavaScriptだけでも動くという、他のプリプロセッサにはあまりない性質を持っています。
とはいえ、読むより触った方が早いと思います。Lessの構文をブラウザ上でその場でコンパイルして結果を確認できるので、先に挙動を見たい方はこちらからどうぞ。
Lessとは
Less(Leaner CSS)は、2009年にAlexis Sellier氏が公開したCSSプリプロセッサです。変数・ネスト・Mixin・演算といった機能をCSSに追加でき、書いたコードは最終的に通常のCSSにコンパイルされます。JavaScriptだけで実装されているのが特徴で、Node.js環境だけでなくブラウザ上でも動作します。
古くはBootstrap 3までがLessを採用していたこともあり、CSSプリプロセッサの中でも歴史が長く、構文が素のCSSに非常に近いため学習コストが低いという評価を受けています。
主な特徴
- 変数(Variables) -
@color: #333;のように値に名前を付けて使い回せる - ネスト(Nesting) - CSSのセレクタ構造をそのままインデントで表現できる
- Mixin - スタイルの塊を関数のように再利用でき、引数やGuard(条件分岐)も書ける
- 演算とカラー関数 -
@base * 2のような計算や、darken()・lighten()などの色操作関数が使える - ブラウザ上での直接コンパイル -
less.render()をJavaScriptから呼び出すだけで、ビルドツールなしにその場でCSSへ変換できる
インストール
CLIツールとしてグローバルにインストールする場合。
npm install -g less
プロジェクトの依存として追加し、ビルド時にコンパイルする場合。
npm install --save-dev less
lessc styles.less styles.css
Lessのサンプルを動かす
下のサンプルは、テキストエリアに書いたLessのソースコードをless.render()でCSSにコンパイルし、その場でページに適用するものです。@primaryや@radiusという変数と、.card { .title { ... } }というネスト、@radius * 2という演算を使っています。
要点だけを抜き出すと、Lessの変数・ネスト・演算は次のように書きます。
@primary: #2f6fed;
@radius: 6px;
.card {
border: 1px solid @primary;
border-radius: @radius;
padding: @radius * 2;
.title {
color: @primary;
font-weight: bold;
}
}
これをブラウザ上でコンパイルして、実際に画面へ反映するサンプルが以下です。テキストエリアの@primaryの色コードを書き換えて「コンパイル」を押すと、下のプレビューカードの色がその場で変わります。
less.render()は非同期関数で、コンパイル済みのCSS文字列をoutput.cssとして返します。それを<style>タグに差し込んでいるだけなので、ビルドツールもバックエンドも一切使っていません。試しに@radiusを20pxにしたり、ネストを1段増やしてみたりすると、Lessのコンパイル結果がどう変わるかが直接確認できます。
基本的な使い方
実際のプロジェクトでは、.lessファイルに変数・ネスト・Mixinをまとめて書き、lesscコマンドでCSSに変換するのが基本的な流れです。
// 変数
@base-color: #333;
@spacing: 8px;
// ネスト
.nav {
background: @base-color;
li {
display: inline-block;
margin-right: @spacing;
a {
color: lighten(@base-color, 40%);
}
}
}
// Mixin(引数付き)
.rounded(@radius: 4px) {
border-radius: @radius;
}
.button {
.rounded(8px);
}
lessc styles.less styles.css
@base-colorや@spacingのような変数、.nav { li { a { ... } } }という入れ子構造、.rounded(@radius: 4px)という引数付きMixinが、Lessの基本文法の中心です。
実践的なユースケース
Mixinとガードでボタンのバリエーションを作る
似たようなボタンを何種類も書くとき、色だけを変えて同じスタイルを繰り返しがちです。LessのMixinに引数を渡せば、共通スタイルを1箇所にまとめられます。さらにwhenによるGuard(条件分岐)を使うと、背景色の明るさに応じて文字色を自動で切り替えることもできます。
.button-variant(@bg; @fg: #fff) {
background: @bg;
color: @fg;
border: none;
border-radius: 6px;
padding: 8px 16px;
}
.button-variant(@bg) when (lightness(@bg) > 60%) {
color: #000;
}
.btn-primary { .button-variant(#2f6fed); }
.btn-success { .button-variant(#2fa84f); }
.btn-ghost { .button-variant(#f0f0f0); }
下のサンプルでは、スライダーで角丸(border-radius)の値を変えるたびにLessのソースを組み立て直し、less.render()で3種類のボタンを一括で再コンパイルしています。
スライダーを動かすと3つのボタンの角丸が同時に変わります。.button-variantというMixinを1回定義するだけで済んでいる点と、when (lightness(@bg) > 60%)というGuardによって明るい背景色(Ghostボタン)だけ自動的に文字が黒くなっている点に注目してみてください。
演算子でスペーシングスケールを自動生成する
余白のサイズがコンポーネントごとにバラバラだと、デザインの一貫性が崩れます。Lessの演算子を使えば、基準となる1つの変数から倍数でスペーシングを組み立てられるので、後から基準値を変えるだけで全体のスケールを調整できます。
@base: 8px;
.box-1 { width: @base * 1; }
.box-2 { width: @base * 2; margin-left: @base; }
.box-3 { width: @base * 3; margin-left: @base; }
.box-4 { width: @base * 4; margin-left: @base; }
以下のサンプルでは、@baseの値を数値入力で変えるたびに@base * 1〜@base * 4を再計算し、4つのボックスの幅と間隔をまとめて再コンパイルしています。
数値を8から20に変えてみると、4本のバーが比率を保ったまま一斉に大きくなります。@base * nという演算をハードコードした数値の代わりに使うことで、スケール全体を1つの変数から管理できるのがLessの演算の強みです。
ブラウザ上でテーマカラーをその場で再コンパイルする
Lessが他のプリプロセッサと一線を画すのは、Node.jsのビルドステップを経由せずにブラウザのJavaScriptだけで完結できる点です。この性質を使うと、ユーザーがカラーピッカーで選んだ色を@primary変数に反映し、darken()やlighten()で自動生成した配色をその場でナビゲーションに適用する、といったテーマカスタマイズ機能を作れます。
@primary: #2f6fed;
.theme-nav {
background: @primary;
border-bottom: 4px solid darken(@primary, 15%);
a { color: lighten(@primary, 40%); }
}
下のサンプルでカラーピッカーの色を変えると、less.render()が再実行されてナビゲーションの背景色・下線・リンク色が同時に変わります。
色を変えるたびに、下線の色がdarken()で自動的に少し暗く、リンク文字色がlighten()で自動的に明るく計算し直されているのが分かります。ビルドツールを挟まずJavaScriptだけでLessを再コンパイルできるからこそ、こうしたリアルタイムなテーマ切り替えを素のCSS変数より柔軟に実装できます。
まとめ
Lessは、変数・ネスト・Mixin・演算・カラー関数といったCSSプリプロセッサの基本機能を、素のCSSに近い構文で提供してくれるツールです。lesscでビルド時にコンパイルする使い方はもちろん、less.render()を使えばブラウザのJavaScriptだけで動的にCSSを生成できる点は、他のプリプロセッサにはあまりない強みです。
Sassほど機能は多くありませんが、その分学習コストが低く、既存のCSSに変数とネストを足すだけでも十分に恩恵を受けられます。まずは手元の1つのCSSファイルに@variableを1つ導入するところから、試してみてはいかがでしょうか。