LESSを用いたCSSの効率化とGulpによる自動コンパイル

前提

前提となる環境は以下の通り。

ツール バージョン
node 7.4.0
npm 4.1.2
gulp 3.9.1

上記環境のインストールについては下記参照
Debian8.7にMEAN開発環境を構築する
Babel+Gulpで始めるES6

LESSとは

CSSをロジカルに記述できるメタ言語。通常のCSSを拡張する形で、主に以下の機能が利用できるようになる。作成したLESSファイルは、LESSコンパイラを通してCSSに変換して利用する。

  • 変数代入
  • 階層構造化
  • 条件分岐
  • ミックスイン
  • 継承
  • 豊富な標準関数

LESS.jsによる動的なコンパイル

LESSは、基本的にコンパイラを用いてデプロイ前に静的に変換するが、コンパイル環境を持たずとも、LESS.jsを用いることでWebブラウザ上で動的にCSSに変換することができる。

LESS.jsはCDNから利用できるので、該当のHTMLページでそれをロードし、それより上でLESSのファイルをCSSと同じようにロードする。下記にその例を示す。

<html>
<head>
  <link rel="stylesheet/less" type="text/css" href="hoge.less">  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/less.js/2.2.0/less.min.js"></script>  
</head>
<body>
</body>
</html>

これで、LESS.jsは読み込まれた時点でリソースに存在するlessファイルをcssに変換する。非常にお手軽ではあるが、ブラウザに変換を任せてしまうこと、コード量が多くなってしまうことから、デプロイ時には静的変換をかけるようにし、LESS.jsの使用は開発中に限ったほうが良いと思われる。

lessコンパイラのインストール

本記事の前提の項で触れているとおり、gulp(3.9.1)が使える状態から始まっているので、ここではgulpでlessを利用するためのパッケージをインストールする

$ sudo npm install -D gulp-less

インストールされたバージョンを確認

$ npm ls gulp-less
degulog@1.0.0 /home/vagrant/less-test
└── gulp-less@3.3.0

gulpにタスクを定義

ここでは、app/styles/style.lessに変更を検知したら、それをcssに変換し、app/styles/build/style.cssに保存するタスクを記述する。

gulpfile.js

var gulp = require('gulp');
var less = require('gulp-less');

gulp.task('less' , function() {
  gulp.src('app/styles/style.less')
      .pipe(less())
      .pipe(gulp.dest('app/styles/build/'));
});

gulp.task('watch' , function() {
  gulp.watch('app/styles/style.less' , ['less']);
});

gulp.task('default' , ['less' , 'watch']);

これで、gulpコマンド実行時と、実行中にファイルが書き換わった際に自動でコンパイルしてくれるのでコーダーは一切意識すること無くLESSだけを記述することができる。

LESS構文例

ここからは、LESSの主な機能について特に意味のない極シンプルなコード例を示す。コードは、変換前のlessファイル、変換後のcssファイルの順で掲載する。

変数の利用

@変数名: 値
の形式で宣言できる。単純な計算や文字列展開も可能。

変換前

@header1: 18px;
@header2: @header1 - 4;
@imgdir: "/img";
h1 {
  font-size: @header1;
}
h2 {
  font-size: @header2;
}
.content {
  background-image: url("@{imgdir}/bg1");
}

変換後

h1 {
  font-size: 18px;
}
h2 {
  font-size: 14px;
}
.content {
  background-image: url("/img/bg1");
}

階層構造化

ある要素の子要素にのみスタイルを振ると行った場合に有効。もう冗長にしか見えないコードを書く必要がない。

変換前

h1 {
  font-size: 18px;
  a {
    text-decoration: none;
  }
}

変換後

h1 {
  font-size: 18px;
}
h1 a {
  text-decoration: none;
}

条件分岐

変数の値を元に、スタイルの設定を分岐させる

変換前

@width: 400px;

.content when (@width <= 400px) {
  font-size: 12px;
}
.content when (@width > 400px) {
  font-size: 14px;
}

変換後

.content {
  font-size: 12px;
}

ミックスイン(関数)

イメージは関数呼び出し?宣言済みのスタイルを取り込むことができる。

変換前

.my-header(@font-size: 16px) {
  text-align: center;
  font-size: @font-size;
}
h1 {
  .my-header();
}
h2 {
  .my-header(14px);
}

変換後

h1 {
  text-align: center;
  font-size: 16px;
}
h2 {
  text-align: center;
  font-size: 14px;
}

継承

ミックスインと似ているが、生成されるCSSを見ると分かる通り、こちらのほうがコード量が少なく、親子関係もわかりやすくなる。

変換前

.my-header {
  text-align: center;
}
h1 {
  &:extend(.my-header);
  color: red;
}
h2 {
  &:extend(.my-header);
  color: blue;
}

変換後

.my-header,
h1,
h2 {
  text-align: center;
}
h1 {
  color: red;
}
h2 {
  color: blue;
}

豊富な関数

LESSには様々な関数が用意されている。以下はその1例で、@base-colorを元に、それより10%明るい色を計算して設定してくれる

変換前

@base-color: #aa1111;
h1 {
  color: lighten(@base-color , 10%);
}

変換後

h1 {
  color: #d81616;
}

所感

  • 個人的には、階層構造化できる点が一番大きい。CSSでいつも冗長な記述をしている気がしてならなかったので
  • Node環境を用意できなくてもJavaScriptファイルをロードするだけでLESSが使えるというのは大きい。これならデザイナーさんなども手軽に利用できる
  • 最近学習した技術と比較しても、覚えることが非常に少なくそれでいてパワフルな生産性を生み出せるコスパの良い技術だと思った。従来のCSSに対して上位互換を持っている分、既存のCSSをそのまま使いつつ一部分だけLESSで拡張すると行ったこともできるので、導入コストは非常に小さいと思われる

参考

コメントを残す

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