ただのブログです

技術的な物とかを主に。主にWeb系がメイン。いつか、職業エンジニアになりたい。

LESSについて布教用の資料書いた

cssを使えなんて縛りがあるわけでもないのにcssでかかれると困るのです。
cssなんてメンテしたくない。

そう、そこで何番煎じか分からないけどlessの布教用の資料の下書き書いた。
あんまためになる情報書いてない。布教用。

scssよりもless派です。
既存のcssをより扱いやすいからlessです。
Play frameworkだってless推奨なんです。

明日から会社でザビエルのごとくLESSを布教してきます。

  1. 事前準備
  2. モジュールのインストール(新規プロジェクト)
  3. モジュールのインストール(既存プロジェクト)
  4. 初めてのLESS
  5. 変数を使う
  6. 自動でcssに変換する
  7. 他のクラスを拡張したクラスを定義する
  8. 他のクラスを拡張したクラスを定義する②
  9. 関数(計算式)を使う
  10. LESSのカッコイイ使い方(!?)

事前準備

Node.js、npmのインストール

Windows

Node.js へ行き、INSTALLからダウンロードされたファイルに従いインストールを完了して下さい。

Mac( Home brewは入っている前提 )

brew install node

次にコンソールを開いてください。(windowsならWindowsキー+Rを押して、cmdと入力します。Macならアプリケーション→ユーティリティからターミナルをクリックしてください) 今回作成するサイトのディレクトリに移動します。

ex)
# windows
cd c:\workspace\html-edu-1
# mac
cd /home/user/workspace/html-edu-1

以降の作業は全てこのディレクトリで行います。(Macであればrootとして実行するか、全てのコマンドの先頭にsudoとつけてください)

grunt-cliのインストール

コンソールで下記のコマンドを実行してください。

npm install -g grunt-cli

必要モジュールのインストール(新規プロジェクトの場合)

ルートディレクトリにpackage.jsonというファイルを作成します。
ファイルの内容は下記で行きましょう。

{
  "name": "html-edu-1",
  "version": "0.0.0"
}

※ npm initというコマンドして、package.jsonを生成する方法もあります。

まず、gruntをインストールします。
このgruntというモジュールは色々便利にしてくれる魔法のモジュールです。

npm install grunt --save-dev

--save-devというのを忘れずに書いてください。
この--save-devを書いて実行すると、先ほどのpackage.jsonにインストールしたモジュールが自動で追記されます。 ためにし、上記のコマンドを実行してみた後にpackage.jsonを開いてみてください。
"devDependencies": {
"grunt": "~0.4.1"
}
のような記載した覚えのないコードが追加されていると思います。

less化するにあたって、lessをcssに変換するモジュールをインストールします。

sudo npm install grunt-contrib-less --save-dev

自動でlessをcssに変更するために、watchモジュールをインストールします。

sudo npm install grunt-contrib-watch --save-dev

Gruntfileの作成

ルートディレクトリにGruntfile.coffeeというファイルを作成します。
このGruntfileに、に色々なツールを実行するための手順を記載していきます。

まずは、下記の内容を記入していきましょう。

# このメソッドの中に全て定義していきます。
module.exports = (grunt) ->
  # 先ほどインストールしたモジュールをロードするようにします
  grunt.loadNpmTasks 'grunt-contrib-less'
  grunt.loadNpmTasks 'grunt-contrib-watch'

  # initConfig
  grunt.initConfig
    # lessの設定を行います
    less:
      compile: 
        files: [
          "css/index.css":"less/index.less"   # less/index.lessファイルを、css/index.cssに変換します
        ]
    # watchの設定を行います
    watch:
      less:
        files: "less/**/*.less"   # lessディレクトリ以下の拡張子がlessのファイルが更新されたのを感知したら
        tasks: ["build"]          # 後述のbuildコマンドを実行します
  
  # end initConfig


  grunt.registerTask "run", ["watch"] # run というコマンドを実行すると watchに設定された動作を行います。
  grunt.registerTask "build", ["less"] # build というコマンドを実行すると lessをcssに変換します。

コンソールで

grunt build

と入力してみてください。

何も間違っていなければ、

Done, without errors

と表示されるはずです。

必要モジュールのインストール(既存プロジェクトの場合)

既に誰かが上記の作業をしている場合、package.jsonやGruntfile.coffeeというファイルは既に存在しているはずです。

その場合は、コンソールで下記のコマンドを入力するだけで作業環境が構築できます。

npm install

初めてのLESS

LESSはCSSへの後方互換を持っています。
そのため、だたのCSSをそのままLESSファイルとして扱うことが出来ます。
試しに、lessフォルダを作成し、
css/index.css

less/index.less
にリネームしてしましょう。

最初の構築で、

    less:
      compile: 
        files: [
          "css/index.css":"less/index.less"   # less/index.lessファイルを、css/index.cssに変換します
        ]

と既に記載されているため、ただリネームするだけでOKです。
もし他のlessファイルもcssに変換したければ

    less:
      compile: 
        files: [
          "css/index.css":"less/index.less"   # less/index.lessファイルを、css/index.cssに変換します
          "css/style.css":"less/style.less"   # 変換するlessを追加する
        ]

と追記して下さい。

ただ、lessに名前変更しただけではもちろんレイアウトは崩れてしまいます。

<link href="css/index.css" rel="stylesheet" type="text/css" media="all" />

そのため、このリンクを切らないようにindex.cssを作成しましょう。

コンソールで下記のコマンドを実行してください。

grunt build

出力結果に、Done without Errorsと出れば成功です。
もし、cssのシンタックスエラー等があればその情報がコンソールに表示されるので該当箇所を修正して下さい。

成功した場合、css/index.cssが作成され、ページのレイアウトも元に戻っていると思います。

LESSはただのCSSを書いても問題ないのです!

変数を使う

通常のcssでは不便な問題が多々あります。
例えば、同じ幅を表現する場合我々は下記のようなコードを書かなければなりません。

.main_section {
  clear:both;
  margin-bottom:50px;
}
.sub_section {
  background:url(../img/bg-section.gif) center repeat-y;
  margin-bottom:50px;
  width:710px;
}

ここでのmargin-bottomに注目してみてみましょう。
この50pxという値は、 .main_sectionと.sub_sectionそれぞれのクラスで同じ値を使用しなければなりません。
もし50pxではなく、48pxにしたい場合、2か所を修正しなければなりません。
この事は作業工数を増加させる他、修正漏れがあった場合にレイアウト崩れが起こってしまう不具合の原因となり得ます。

// 変数宣言
@contents-margin-bottom: 50px;

.main_section {
  clear:both;
  margin-bottom: @contents-margin-bottom;
}

.sub_section {
  background:url(../img/bg-section.gif) center repeat-y;
  margin-bottom: @contents-margin-bottom;
  width:710px;
}

このlessからcssを再度生成するために再度

grunt build

を実行しましょう。

生成されたindex.cssを見てみれば

.main_section {
  clear:both;
  margin-bottom:50px;
}
.sub_section {
  background:url(../img/bg-section.gif) center repeat-y;
  margin-bottom:50px;
  width:710px;
}

となっているのが分かると思います。
こうやって設定値としてもっておけば、幅の調整等はもちろん少ない工数、全箇所を一度に修正ができるようになりますよね?

LESSはこういったCSSの問題を解決してくれる言語なのです!

自動でcssに変換する

先ほどの例では二度

grunt build

というコマンドを打つ必要がありました。
修正するたびに毎回このコマンドを打っていたのでは、非常に面倒です。

そこで、今度は

grunt run

と実行してみましょう。

Runnning "watch" task

と画面に出力されればOKです。

この状態で試しに先ほどの

@contents-margin-bottom: 50px;

@contents-margin-bottom: 80px;

と変更して保存してみましょう。

保存した瞬間に、何やら色々と出力されたと思います。 これは最初にインストールしたgrunt-contrib-watchモジュールを利用して、保存した瞬間にlessをcssに変換ということをやってくれます。

作業の初めに

grunt run

と実行してしまえば、lessからcssの変換作業等いちいち手作業でやらずとも保存した瞬間にcssが作られるようになるのです!

他のクラスを拡張したクラスを定義する

LESSではMixinsと呼ばれる機構を提供しています。
この機構は何かというと、他のクラスを混ぜ合わせたクラスを定義できるという機構です。
説明ではよく分からないので試しに定義してみましょう。

.sub_section:after {
  content: "."; display: block; visibility: hidden; height: 0.1px; font-size: 0.1em; line-height: 0; clear: both;
}

.banner_section ul:after {
  content: "."; display: block; visibility: hidden; height: 0.1px; font-size: 0.1em; line-height: 0; clear: both;
}

この2つのcssはそれぞれ同じスタイルを、違う要素に適用しようとしています。
このスタイルは変更される頻度は低いですが、もし新しいIEがでて、新型IEのバグでこのスタイルでは崩れてしまう。といった状況を考えてみましょう。(無いとは思いますが)
全てのcssを全部変更するのは非常に工数がかかります。
そこで、先にクリアフィックスのクラスを作りそれを利用してみましょう。

.clearfix {
  content: "."; display: block; visibility: hidden; height: 0.1px; font-size: 0.1em; line-height: 0; clear: both;
}
.sub_section:after {
  .clearfix;
}
.banner_section ul:after {
  .clearfix;
}

通常のプロパティの書き方と異なり、同じスタイルを適用するcssのクラス名を記載します。

このように、同じcssを利用したい場合は、コピー&ペーストせずとも簡単に使えますし、もし修正が必要になった場合も.clearfixだけを修正すれば全て修正されるのです!

他のクラスを拡張したクラスを定義する②

先ほどのMixinsという機構はもっと応用的な機能もサポートしています。 例えばborder-radiusを指定する例を見てみましょう。

.border-radius {
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  -ms-border-radius: 5px;
  -o-border-radius: 5px;
  border-radius: 5px;
}

各ブラウザベンダーの独自実装に対応するスタイルを記入しなければなりません。
先ほどのMixinsの例の書き方では、5px以外のスタイルを再利用することができません。
そこで値を変更可能なCSSとして定義してみます。

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

このように書きます。
(変数名:初期値)または(変数名)という宣言が可能です。
このように宣言されたスタイルは

.foo {
  .rounded-corners(10px);
}
.bar {
  .rounded-corners;
  // .rounded-corners(5px);と同じ
}

このように利用可能になり、面倒なブラウザごとの指定方法を一度にまとめて定義できたり、似たようなスタイルをまとめて定義・変更するのに役に立ちます!

関数(計算式を使う)

cssでさらに面倒なことはpxを計算を行わなければならないときです。

@foo-height:45px;
@bar-margin-top:50px; // fooのheightより5px大きくしたい
.foo {
  height:@foo-height;
}
.bar {
  margin-top:@bar-margin-top; 
}

こういった場合

@foo-height:45px;
.foo {
  height:@foo-height;
}
.bar {
  margin-bottom:@foo-height + 5; // heightより5px空けたい
}

このように計算式を利用してスタイルを定義してやることで、毎回毎回px計算する必要を無くすことができます!

LESSのカッコイイ使い方(!?)

かっこいいというほどではないですが、LESSの運用についてプラクティス。

共通lessを分離して管理

  • variables.less
  • utility.less

と言ったファイルを定義します。

variables.lessには全てのレギュレーション定義を記入します。

@red:#f58787;
@green:#87f587;
@blue:#8787f5;
@white:#f5f5f5;
@black:#303030;

このように利用することでカラーデザインの微調整等を一括で行えるようにします。

@nav-height:42px;
@article-width:710px;
@article-padding-rl:10px;
@section-width: @article-width / 2 - @article-padding-rl;

大域レイアウト等もこのように全て一か所で宣言します。

utilities.lessには汎用的なlessを記載すると良いでしょう

.border-radius(@radius) {
  -webkit-border-radius: @radius;
  -moz-border-radius: @radius;
  -ms-border-radius: @radius;
  -o-border-radius: @radius;
  border-radius: @radius;
}

.clearfix {
  content: "."; display: block; visibility: hidden; height: 0.1px; font-size: 0.1em; line-height: 0; clear: both;
}

このようにページデザインとは本来関係ないスタイルを別途定義しておけば、他のウェブページでも再利用できます。

あとはこれらを実際のlessでimportするだけです!

@import "variables.less";
@import "utilities.less";

各パーツを分離して管理

場合によってはcssのファイルが数百行~数千行に及ぶようなデザインが必要な場合があります。 そんな時にはレイアウトファイルの分離を図ってみて下さい。

  • navbar.less
  • footer.less
  • sidebar.less
  • article.less
  • article-thema-green.less
  • article-thema-red.less
  • article-thema-blue.less

パーツごとにlessファイルを分け、 style.lessで

@import "navbar.less;
@import "footer.less;
@import "sidebar.less;
@import "article.less;
@import "article-thema-green.less;
@import "article-thema-red.less;
@import "article-thema-blue.less";

とだけします。

そうすれば、 .article .thema-green .article .thema-red .article .thema-blue 等のスタイルの行を探さなくて済むようになりますし、バージョン管理のコミットログでどのパーツの部分がスタイル変更されたのかが分かりやすくなります。