CSS拡張メタ言語「LESS」の使い方

CSS拡張メタ言語「LESS」の使い方

Posted at October 3,2012 1:55 AM
Tag:[CSS, JavaScript, LESS]

CSSを効率的に書くための拡張メタ言語「LESS」の使い方を紹介します。

LESS
LESS

1.「LESS」でできること

簡単な例として、次のように変数「@xxx」を使って値を定義することができます。

@radius: 10px;
@bg-color: #fff;
@padding: 10px;
.foo {
  background: @bg-color;
  padding: @padding;
  border-radius: @radius;
  -webkit-border-radius: @radius;
  -moz-border-radius: @radius;
}
.bar {
  background: @bg-color;
  padding: @padding;
  border-radius: @radius;
  -webkit-border-radius: @radius;
  -moz-border-radius: @radius;
}

話を戻して、「LESS」でできることは大きく分けて以下の4つです。カッコ内はLESS公式サイトの表現です。

  • 変数の利用が可能(Variables)
  • セレクタの入れ子が可能(Nested rules)
  • 関数の利用(Mixins)
  • 演算(Operations)

上記の4つはどのサイトでも同じように紹介されていますが、公式ドキュメントをざっと目をとおしたところ、さらに以下の機能もあることが分かりました。

  • パターンマッチ
  • 条件判定
  • 配色関数
  • 数値関数
  • JavaScript実行

その他、ネームスペース/変数のスコープ/コメント/インポート/エスケープなど機能満載です。CSSから拡張していくだけなので、CSSを知っている人なら導入しやすいと思います。

さしづめ、「CSS版jQuery」といったところでしょうか。

LESSはJavaScriptで書かれていて、「.css」ファイルの代わりに「.less」ファイルを用意します。

2.基本設定

まず、「LESS」の公式サイトにアクセスして、「Download less.js」をクリック。

「LESS」の公式サイト

ダウンロードした「less-1.x.x.min.js」を、LESSを利用したいサーバにアップロードします。ファイル名は適宜リネームしてください(そのままでもOK)。

LESSを利用したいウェブサイトやブログのhead要素に以下を記述します。script要素のsrc属性値はアップロードしたファイル名とあわせてください。

<link rel="stylesheet/less" type="text/css" href="styles.less">
<script src="less-1.x.x.min.js" type="text/javascript"></script>

あとは、link要素のhref属性に記述した「styles.less」を用意して、LESSのお作法にしたがってCSSを記述するだけです。

以下、機能とサンプルについて解説します。

3.変数を利用する

変数を利用することができます。変数の定義は文字列の先頭に「@」を付与し、CSSのプロパティと同じようにコロンで区切って右側に値を記述します。

サンプルとしてcolorプロパティの値に変数を利用してみます。

@blue: #00ffff;
h3 { color: @blue; }

出力結果は次のようになります。

h3 { color: #00ffff; }

4.変数の値を演算する

また変数を演算することも可能です。下のサンプルは変数@nice-blueの値「#5B83AD」の各桁に「1」を加算して、変数@light-blueに設定したものです。

@blue: #5B83ad;
@light-blue: @blue + #222;
h3 { color: @light-blue; }

出力結果は「#5B83ad」に「#222222」を加算した「#7da5cf」が設定されます。

h3 { color: #7da5cf; }

5.変数の値を変数名として利用する

ネットではあまり紹介されていないようですが、「@@」と記述することで、変数の値をさらに変数として利用することができます。

@foo: "This is a pen.";
@var: 'foo';
content: @@var;

出力結果は次のようになります。

content: "This is a pen.";

6.セレクタの入れ子

セレクタを入れ子にすることができます。

まず、次のようなCSSを用意します。

h3 { color: blue; }
h3 .foo {
  font-size: 100%;
}
h3 .bar {
  width: 450px;
}
h3 .bar:hover {
  text-decoration: underline;
}

次のように1つのセレクタに入れ子としてまとめることができ、見通しがよくなります。擬似クラスは「&」で表現します。

h3 {
  color: blue;
  .foo {
    font-size: 100%;
  }
  .bar {
    width: 450px;
    &:hover { text-decoration: underline; }
  }
}

7.セレクタの入れ子(複数クラスセレクタにマッチ)

6項と同じ機能ですが、複数のクラスセレクタにマッチさせる場合とそうでない場合の記述方法について解説します。

.foo.bar {
  float: right;
}
.foo .bar {
  padding: 5px;
}

複数のクラスセレクタにマッチさせる場合、入れ子にしたクラスセレクタを示すピリオドの直前に「&」を付与し、そうでない場合はピリオドのみで表現します。

.foo {
  &.bar {
    float: right;
  }
  .bar {
    padding: 5px;
  }
}

複数のクラスセレクタにマッチさせる手法の詳細は「CSSでクラスセレクタをくっつけて並べる方法」をご覧ください。

8.関数の利用

関数を利用することで、同じプロパティの記述をひとつにまとめることができます。

関数の定義は、クラスセレクタと同じ形式で次のように定義します。

.padding {
  padding-top: 3px;
  padding-bottom: 5px;
}

この関数を利用するには、関数を呼び出すプロパティに関数名(セレクタ名)を記述すればOKです。

.foo {
  margin: 5px;
  .padding;
}
.bar {
  margin: 3px;
  .padding;
}

出力結果は次のように、関数の内容が呼び出し元に反映されます。

.foo {
  margin: 5px;
  padding-top: 3px;
  padding-bottom: 5px;
}
.bar {
  margin: 3px;
  padding-top: 3px;
  padding-bottom: 5px;
}

9.関数にパラメータを指定

関数にまとめただけではダイナミックな値の変更に対応できません。そこでパラメータの登場です。

関数の定義は先程同様ですが、関数に値を渡すために、カッコをつけて次のように定義します。この場合は「@radius」という変数がパラメータで、「5px」はデフォルト値を示します。

.border-radius (@radius: 5px) {
  border-radius: @radius;
  -moz-border-radius: @radius;
  -webkit-border-radius: @radius;
}

関数を利用する側は、関数名の右側にカッコをつけ、カッコ内に値を設定します。差が分かるようにカッコがないサンプルも加えておきます。

#foo {
  .border-radius(4px);
}
.bar {
  .border-radius(6px);
}
h3 {
  .border-radius;
}

出力結果は次のように、関数呼び出し時に指定した値がプロパティの値として反映されます。

#foo {
  border-radius: 4px;
  -moz-border-radius: 4px;
  -webkit-border-radius: 4px;
}
.bar {
  border-radius: 6px;
  -moz-border-radius: 6px;
  -webkit-border-radius: 6px;
}
h3 {
  border-radius: 5px;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
}

10.関数に複数パラメータを指定

関数のパラメータは複数指定できます。複数指定したパラメータは関数の中で「@arguments」で一括表示できます。

.shadow (@x: 0, @y: 0, @blur: 1px, @color: #000) {
  box-shadow: @arguments;
  -moz-box-shadow: @arguments;
  -webkit-box-shadow: @arguments;
}
#header {
  .shadow(2px, 5px);
}

出力結果は次のようになります。

#header {
  box-shadow: 2px 5px 1px #000;
  -moz-box-shadow: 2px 5px 1px #000;
  -webkit-box-shadow: 2px 5px 1px #000;
}

11.関数パラメータにパターンマッチを利用

パターンマッチは、同じ関数名で振舞いを変えたい場合に利用します。

まず、振舞いの異なる関数を3つ定義します。振舞いを変えるキーとなるのは、第1パラメータの文字列「dark」「light」です。3つめの関数の「@_」は常に呼び出されるための指定です。

.mixin (dark, @color) {
  color: darken(@color, 30%);
}
.mixin (light, @color) {
  color: lighten(@color, 20%);
}
.mixin (@_, @color) {
  display: inline;
}

次に変数「@switch」と関数呼び出し部分を記述します。

@switch: light;
h3 {
  .mixin(@switch, #888);
}

出力結果は、第1パラメータが「light」の関数「.mixin」と、第1パラメータが「@_」の関数「.mixin」を呼び出した内容が反映されます。

h3 {
  color: #bbbbbb;
  display: inline;
}

変数「@switch」を「dark」に変更すれば、出力結果は、第1パラメータが「dark」の関数「.mixin」と、第1パラメータが「@_」の関数「.mixin」を呼び出した内容が反映されます。

h3 {
  color: #3c3c3c;
  display: inline;
}

12.条件つき関数

関数を実行する際にパラメータの条件で振り分けることが可能です。条件をつけるには、関数パラメータの直後に「when ( 条件 )」を追加します。

「lightness()」の部分は、プログラミングが分かる人はライブラリ(特定の計算を行う予め用意された関数)のようなものと思ってください。

サンプルとして次の3つの条件付関数を定義します。

.mixin (@a) when (lightness(@a) >= 50%) {
  background-color: black;
}
.mixin (@a) when (lightness(@a) < 50%) {
  background-color: white;
}
.mixin (@a) {
  color: @a;
}

これに次のCSSを定義します。

.foo { .mixin(#ddd) }
.bar { .mixin(#555) }

出力結果は、関数「.mixin」を起動したときにパラメータの値をlightness()で判定し、判定がマッチしたそれぞれの関数が実行されていることが分かります。

.foo {
  background-color: black;
  color: #ddd;
}
.bar {
  background-color: white;
  color: #555;
}

「when」の判定式は次の5つが用意されています。

  • >(大きい)
  • >=(等しいか大きい)
  • =(等しい)
  • =<(等しいか小さい)
  • <(小さい)

「not」演算も可能です。

.mixin (@foo) when not (@foo > 0) { ... }

「and」演算も可能です。

.mixin (@foo, @bar) when (@foo < 10) and (@bar > 0) { ... }

whenの条件式をカンマで区切って、複数設定することもできます。これにより複雑な条件の設定も可能です。

.mixin (@foo) when (@foo > 10), (@foo < -10) { ... }

パラメータ同士の判定も可能です。

.max (@foo, @bar) when (@foo > @bar) { width: @foo }
.max (@foo, @bar) when (@foo < @bar) { width: @bar }

また、通常の変数とパラメータの判定も可能です。

@type: mobile;
.mixin (@foo) when (@type = mobile) { ... }
.mixin (@foo) when (@type = smartphone) { ... }

パラメータの型判定も行えます。

.mixin (@foo, @bar: 0) when (isnumber(@bar)) { ... }
.mixin (@foo, @bar: black) when (iscolor(@bar)) { ... }

「isnumber」はライブラリで、数値型である場合に条件が真となります。型判定のライブラリは次の5種類が用意されています。

  • iscolor
  • isnumber
  • isstring
  • iskeyword
  • isurl

「px」や「%」など、単位の判定が行えるライブラリも用意されています。

  • ispixel
  • ispercentage
  • isem

13.演算

4項でも解説しましたが、値の演算が可能です。

まず、変数を定義します。

@bar: 5%;

変数を演算して別の変数の値にできます。

@foo: @bar * 2;

変数同士の加算も可能です。

@hoge: @foo + @bar;

変数だけでなく、値自体の演算も可能です。

color: #666 / 3;

複雑な計算も簡単に行えます。

background-color: @color + #222;
height: 100% / 2 + @height;

異なる単位も理解できるようです。

@foo: 1px + 5;

演算の優先順位も数学と同様、カッコで実現できます。

width: (@foo + 5) * 2;

14.配色

配色を変更する関数が用意されています。

lighten(@color, 10%);     // 明度を@colorより10%明るく
darken(@color, 10%);      // 明度を@colorより10%暗く
saturate(@color, 10%);    // 彩度を@colorより10%高く
desaturate(@color, 10%);  // 彩度を@colorより10%低く
fadein(@color, 10%);      // 透明度を@colorより10%減らす
fadeout(@color, 10%);     // 透明度を@colorより10%増やす
fade(@color, 50%);        // 透明度を@colorの50%にする
spin(@color, 10);         // 色相を@colorより10度大きく
spin(@color, -10);        // 色相を@colorより10度小さく
mix(@color1, @color2);    // @color1と@color2の配色を混ぜる

色情報を取得する関数も用意されています。

hue(@color);        // @colorの色相
saturation(@color); // @colorの彩度
lightness(@color);  // @colorの明度
alpha(@color);      // @colorのアルファチャネル

ある色のチャンネルに基づいて新しい色を作成したいときに有効です。

@new: hsl(hue(@old), 45%, 90%);

15.数値関数

数値関数も用意されています。

round(1.67); // 値を四捨五入(「2」を返却)
ceil(2.4);   // 値を切り上げ整数化(「3」を返却)
floor(2.6);  // 値を切り捨て整数化(「2」を返却)
percentage(0.5); // 値をパーセント表示(「50%」を返却)

16.ネームスペース

定義した関数をグループ化したい場合に利用します。ネームスペースはIDセレクタと同様、先頭に「#」をつけます。

#name {
  .button1 () {
    margin: 3px;
    color: #333;
  }
  .button2 { ... }
  .button3 { ... }
}

この関数を呼び出すには次のように記述します。

h3 a {
  display: block;
  #name > .button1;
}

17.変数のスコープ

変数のスコープは、関数内で参照している場合は、最初に関数内のローカル変数を探し、なければグローバル変数を参照します。

@bar: #f00;
 
h2 {
  @bar: #333;
  .header {
    color: @bar; // '#333'を表示
  }
}
 
h3 {
  color: @bar; // '#f00'を表示
}

18.コメント

全体を「/* ... */」で括るか、または行頭に「//」を付与することで、コメントとして認識されます。

/* This is comment block. */
.foo { margin: 2px; }

または

// This is comment line.
.foo { margin: 2px; }

19.インポート

ファイルをインポートすることができます。「.less」はオプションのようです。

@import "library.less";
@import "library";

インポートファイルを処理させたくない場合は「.css」を利用します。

@import "library.css";

20.変数の識別

文字列に変数を含ませる場合、Perlと同じように変数名をカーリーブラケット(カーリーブレース)で括ることで変数を正しく識別させることができます。

@base-url: "http://assets.fnord.com";
background-image: url("@{base-url}/images/bg.png");

21.エスケープ

エスケープする場合、エスケープ文字として「~」を利用します。

.class {
  filter: ~"ms:alwaysHasItsOwnSyntax.For.Stuff()";
}

出力結果は次のようにダブルクォーテーションが除去されます。

.class {
  filter: ms:alwaysHasItsOwnSyntax.For.Stuff();
}

22.JavaScriptの実行

バッククォートを利用することで、ファイル内でJavaScriptを利用できます。

@var: `"hello".toUpperCase() + '!'`;

出力結果は次のようになります。

@var: "HELLO!";

DOMオブジェクトにアクセスすることも可能です。

@height: `document.body.clientHeight`;

JavaScriptとライブラリを組み合わせれば、windowオブジェクトの配色をCSSで利用するといった技も簡単に行えます。

@color: color(`window.colors.baseColor`);
@darkcolor: darken(@color, 10%);

2012.10.05
本文を改善しました。

2012.10.06
概要を修正しました。

関連記事
zenback
人気エントリー
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)