Bourbon x Neat

BourbonはSassのmixinライブラリ、NeatはBourbonで作られたグリッドフレームワークです。

Bourbon/Neatのインストール

% gem install bourbon
% gem install neat

インストールが済んだら、bourbon installでBourbonのファイル一式を、neat installでNeatのファイル一式をプロジェクトディレクトリに配置します。

% bourbon install
Bourbon files installed to bourbon/  
% neat install
Neat files installed to neat/  
% ls
bourbon neat  

後はmain.scssなどのエントリーポイントとなるSASSファイルでBourbonとNeatをインポートします。

@import "bourbon/bourbon";
@import "neat/neat";

NeatBourbonに依存するので、先にBourbonをインポートすることに注意してください。

Bourbonの基本

まずは簡単な要素のスタイリングをして、雰囲気を掴んでみます。

<div class="box">BOX</div>  
.box {
  margin: 0 auto;
  background-color: #eee;
  background-image: -webkit-linear-gradient(#eee, #ccc);
  background-image: linear-gradient(#eee, #ccc);
  width: 300px;
  height: 100px;
  border-style: solid dashed dotted none;
  border-width: 3px;
}

Bourbonを使うとboxクラス要素のスタイルは以下のように書くことができます。

.box {
    @include margin(0 auto);
    @include linear-gradient(#eee, #ccc);
    @include size(300px 100px); // width, heightを指定
    @include border-style(solid dashed dotted null); // TOP-RIGHT-BOTTOM-RIGHT
    @include border-width(3px);
}

@includeを使ってBourbonで定義されているMixinを利用します。Bourbonで利用可能なMixinはドキュメントを参照して、色々試してみましょう。

Bourbonは、BootstrapのようなCSSフレームワークと異なり、CSS側で要素に対してスタイルを定義していくのが主になります。例えばbtn-primaryのように、Bootstrapで用意されているクラス名をつけると、その通りのスタイルを持つボタンになるわけではありません。

現バーション(4.2.3)ではbuttonというMixinを使うと、Bourbonでスタイリングされたボタンを作ることができますが、次のメジャーアップデートでは無くなるようです。この様な定義済スタイリングに関してはBittersを利用することになります。また、タブなどのコンポーネント、よく使われるパターンはRefillsにまとまっています。

Neatの基本

BourbonはSASSのMixin集ですが、Neatはグリッドフレームワークです。Bootstrapではrow/container/col-sm-6などのクラス名を要素に付けていくのに対して、NeatはBourbonと同様に.scss上でページのグリッドを定義していきます。

以下の様なHTMLで、2カラムのレイアウトを作る場合を考えてみます。

<section id="profile">  
  <div class="wrapper">
    <section class="primary-col">
      <h3>Bourbon</h3>
      <p>A simple and lightweight mixin library for Sass.</p>
    </section>
    <section class="secondary-col">
      <h3>Neat</h3>
      <p>A lightweight semantic grid framework for Sass and Bourbon.</p>
    </section>
  </div>
</section>  

Neatでは、このような素のHTMLに対してスタイルシートからレイアウトを定義していきます。

#profile {
    .wrapper {
        @include outer-container;

        .primary-col {
            @include span-columns(6);
        }

        .secondary-col {
            @include span-columns(6);
        }
    }
}

outer-containerはグリッドの最も外側の要素で定義し、これがグリッドのコンテナになります。コンパイルされるとmax-widthが設定され、左右のmarginautoになり要素がセンタリングされます。max-widthの値はデフォルトで16pxを基準として、1088pxをem換算した値である68emになります。16pxはBourbonのソースbourbon/settings/_px-to-em.scssで定義されている変数$em-baseの値です。局所的にコンテナの幅を変更したい場合にはouter-container(480px)のように引数を渡します。グローバルに幅を変更したい場合は、独自に_variables.scssなどを用意し、$max-width: em(960);のように$max-width変数を定義しておきます。

カラムとなる要素にはspan-columnsMixinを使い、引数にカラム数を渡します。Neatのデフォルトでは12カラムのグリッドです。カラムをネストしたい場合は、親要素のカラム数を渡す必要があります。

<section class="primary-col">  
    <h3>Bourbon</h3>
    <p>A simple and lightweight mixin library for Sass.</p>
    <div class="child-col">Child column</div>
    <div class="child-col">Child column</div>
  </section>
.primary-col {
    @include span-columns(6);

    .child-col {
        @include span-columns(3 of 6);
    }
}

レスポンシブなレイアウトを作る

Neatではnew-breakpointを使ってデバイスのスクリーンサイズに応じたブレークポイントを変数として宣言できます。

$mobile: new-breakpoint(max-width: 480px);
$desktop: new-breakpoint(mix-width: 960px);
#profile {
    .wrapper {
        @include outer-container;

        .col {
            @include fill-parent(); // 親要素のコンテナの幅を埋める(width:100%)

            @include media($desktop) {
                @include span-columns(6);
            }

            &.primary-col {
                @include fill-parent();

                @include media($desktop) {
                    @include span-columns(6);
                }

                .child-col {
                    @include span-columns(3 of 6);
                }
            }

            &.secondary-col {
                @include span-columns(6);
            }
        }
    }
}

まとめ

Bootstrapはマークアップに適当なクラスをつけていけば、それなりのデザインのページがすぐにできるのが利点だと思います。社内ツールや定型的なデザインのページ、手早く作りたい場合はBootstrap、よりスタイルヘビーなページ向けにはBourbone/Neat(/Bitters/Refills)の組み合わせで利用していこうかという印象です。