LESSで3倍ラクするスマートフォンコーディング

第9回LESSのメリットを最大限に生かした書き方

前回はMedia Queriesの利用方法とその難点、LESSのコンパイラを利用して少しラクする記法をご紹介しました。

今回はさらに掘り下げて、処理をmixinとして作成し、LESSのメリットを最大限活かす方法をご紹介します。

自動化のポイント

まず、前回のコードをおさらいしておきましょう。

//LESS
body {
     #foo {
          background-size: 320px 480px;
          @media screen and (-webkit-device-pixel-ratio:2){
               background-image: url('bg_x2.png');
          }
          @media screen and (-webkit-device-pixel-ratio:1){
               background-image: url('bg.png');
          }
     }
}

@mediaを毎回書くのは大変ですし、ミスタイプをする確率も高くなります。それならば、まとめてmixinにしてしまうほうが効率的です。

考え方としては、以下のルールの下に自動化を進めます。

  • Retina用(-webkit-device-pixel-ratio: 2)のファイル名(拡張子のぞく)の末尾には、自動的に「_x2」を付ける
  • 「_x2」は後から変更できるようにする
  • バックグラウンドサイズは両方共通

mixinを作る

mixinの全体像

以下がmixinの全体像となります。

//LESS
.switch-ratio(@url,@width,@height){
     @postfix: _2x;
     background-size: @width @height;
     @media screen and (-webkit-device-pixel-ratio:2){
          @url_x2: ~`"@{url}".replace(/\.gif|\.jpg|\.jpeg|\.png/,"@{postfix}"+"$&")`;
          background-image: url(@url_x2);
     }
     @media screen and (-webkit-device-pixel-ratio:1){
          background-image: url(@url);
     }
}

body {
     #foo {
          .switch-ratio('bg.gif',320px,480px);
     }
}


/* Compiled CSS */
body #foo {
     background-size: 320px 480px;
}
@media screen and (-webkit-device-pixel-ratio: 2) {
     body #foo {
          background-image: url('bg_2x.gif');
     }
}
@media screen and (-webkit-device-pixel-ratio: 1) {
     body #foo {
          background-image: url('bg.gif');
     }
}

今までご紹介してきたmixinのなかで、一番複雑なものになってしまいました。しかし、処理の1つ1つは今までご紹介してきた範囲内のものです。1行ずつ見ていきましょう。

画像の情報を定義する

.switch-ratio(@url,@width,@height){

まず、.switch-ratioという名前のmixinを作り、以下の引数を定義します。

  • 画像のurl(@url)
  • 画像の幅(@width)
  • 画像の高さ(@height)
@postfix: _2x;

Retina用画像の名前のルールを定義している部分です。

ここでは、ファイル名の末尾(拡張子は含まない)「_2x」を付けるルールとしました。

background-size: @width @height;

背景として定義する画像の大きさは、実表示サイズとなるので、Retinaでも非Retinaでも大きさは同じです。そのため、先ほど設定した引数@widthと@heightの値をそのまま当てはめます。

@media screen and (-webkit-device-pixel-ratio:2){

ここは、すでにご説明しているように、-webkit-device-pixel-ratio:2(Retina Displayだったら)という条件分岐です。

Retina用の画像を表示させる

@url_x2: ~`"@{url}".replace(/\.gif|\.jpg|\.jpeg|\.png/,"@{postfix}"+"$&")`;

ぱっと見てすごく複雑になってしまいましたが、本連載の第5回でご紹介したJavaScriptで文字を編集するを応用したものです。

まず、@urlの値を文字列として解釈するために、@{url}として記述します。

その上で、urlの文字列に対して.replaceを利用し、

  • 「拡張子が.gifか.jpgか.jpegか.pngだった場合、ファイル名の末尾に@{postfix}(今回の場合は「_2x⁠⁠)を追加する

という処理をJavaScriptで行っています。

そして出来上がった値を、@url_x2という新たな変数に定義しています。

一見複雑になってしまったのは、正規表現を用いているためです。本連載ではJavaScriptの解説までは行いませんが、JavaScriptで文字列を編集できるのはLESSの大きな特徴です。ぜひ少しずつ学んでみてください。

background-image: url(@url_x2);

こちらで先ほど作ったRetina用のファイル名(@url_x2)を、background-imageに設定します。

非Retina用の画像を表示させる

@media screen and (-webkit-device-pixel-ratio:1){
     background-image: url(@url);
}

こちらは第8回でご紹介したコードと同様です。-webkit-device-pixel-ratio:1の場合には、Retina用ではない、元のファイル名(@url)を設定します。

これで、Retina用/非Retina用の画像を切り替えられるmixinの完成です。

あとは以下のように、画像名/画像サイズを引数に入れて、各所で呼び出せば、かんたんに画像を切り替えられます。

.switch-ratio('bg.gif',320px,480px);

いかがでしたでしょうか?

JavaScriptによる文字列の編集や、@mediaによる特殊な記述方法も含めて、mixinを作成してみました。今までの連載の中で一番難しい内容となりました。

しかしその分、一度作ってしまえば、今後記述がよりかんたんになります。後からコードを読み直す際も、意図が明確になり、理解が早まります。ぜひこのような複雑なmixinにも挑戦してみてください。

LESSのコードの書き方は、本回まででいったん終了とします。

次回は、実践的なLESSファイルの分割とファイル構成について解説します。大規模・多人数開発でのTipsもからめてご紹介するので、ぜひお楽しみに!

おすすめ記事

記事・ニュース一覧