Middleman + Foundation + Amazon S3 でのBlogサイト構築(6)Blogサイトのデザイン

前回はmiddleman本体やmiddlemanのblog拡張で使える便利なテンプレートヘルパについて記載しました。 前回まででBlogサイト構築の下準備が整ったので、いよいよというかようやくというか、今回はFoundationを使ってサイトのデザインを作成する部分について記載します。

Foundationとは

イントロダクションでも触れましたが、FoundationはレスポンシブWebデザインにしています。対応のCSSフレームワークです。一応スマホ対応もしたかったので、この分野ではBootstrapが最も有名かと思いますが、今回はBootstrap以外のものを使ってみようと思い、いくつかの候補の中から直感的にFoundationを選択しました。採用したバージョンは去年の11月にリリースされた最新の「5」です。

参考にしたテンプレート

ゼロからサイトを作りこんでいけるだけのスキルもデザイン力が無かったので、レイアウトや配色はStart BootstrapのBlogテンプレートBlogger用のFlatUIテンプレートを参考に(というよりテンプレートほぼそのままに、、、)サイトのデザインを作りこんでいきました。

Start BootstrapはBootstrap 3用のフリーのテンプレートを配布しているサイトです。FoundationはBootstrapとほぼ同等の機能が使えますが、日本語の情報やフリーのテンプレートはBootstrapより遥かに少ないです。なので、今回はStart Bootstrapのテンプレートを足がかりにBootstrapの使い方を学びつつ、それをFoundationに焼きなおす、というワークフローで作業を進めました。

サイトのレイアウト

サイトのレイアウト(サイト全体で共通するhtml)はlayout.erbに書いていきます。本サイトはhamlを使って書いていますが、ひとまずデフォルトのerb前提で話を進めていきます。

Foundationを使って、と偉そうな事を言いましたが、実際に使った機能はGridが主で、あとはTop-barFormsぐらいです。

クラス名は異なりますが、Gridの使い方についてはBootstrapとほぼ一緒です。rowクラスで行を作って、その中にcolumnsクラスでカラムを指定していきます。カラム数は.small-#, .medium-#, large-#クラスで指定します。.small-#がスマホ用、.medium-#がタブレット用、large-#がPC用、というイメージで、一つのdiv要素にこれらのクラスを同時に指定することで画面サイズに合わせてカラム数を変えることができます。(スマホの場合は2、PCの場合はもうちょっと幅を広くしたいので3、といった具合に。)デフォルトでは1行のカラムは12に分割されているので、合計が12になるようにカラムを配置していきます。( 2+8+2、2+10などなど。)

本サイトのレイアウトは大まかには以下のようなhtmlになっています。スマホでも見れるように一応レスポンシブWebデザインにしています。

<html>
<head></head>
<body>
  <!-- header -->
  <div class="row">
    <div class="small-12 columns show-for-medium-up"></div>
  </div>
  <!-- top bar(navbar) -->
  <div class="row">
    <div class="small-12 columns"></div>
  </div>
  <!-- contents -->
  <div class="row">
    <!-- main -->
    <div class="small-12 large-9 columns"></div>
    <!-- sidebar -->
    <div class="small-12 large-3 columns"></div>
  </div>
  <!-- footer -->
  <div class="row">
    <div class="small-12 columns"></div>
  </div>
</body>
</html>

Foundationはモバイルファーストがコンセプトになっていて、モバイル用のレイアウト(small)から作成することが推奨されています。small-#だけ指定した場合は、mediumやlargeの画面でもsmall-#の値が反映されるので、画面サイズに関わらずカラム数を固定にしたい場合はsmall-#だけ指定しておけばOKです。

一方でlarge-#だけ指定した場合はどうなるかというと、mediumやsmallの画面になると先行する要素の下に当該の要素が自動的に周りこんでくれます。本サイトを例にとると、Contentsの部分は large-3のdiv要素(sidebar)が自動的にlarge-9のdiv要素(main)の下に周りこんでくれます。

headerに付与しているshow-for-medium-upクラスは画面サイズに合わせて要素の表示・非表示を切り替えてくれるクラスで、medium以上の画面サイズの場合はheaderを表示する(smallの画面サイズの場合は表示しない)ための指定です。反対にshow-for-small-onlyと指定して、smallの画rhtmlでのみ表示させることなどもできます。この類のクラスはFoundationではVisibilityというカテゴリにまとめられています。

本サイトのレイアウトについてはGridに着目したモックアップを作成したのでこちらも参考になればと思います。(※モックアップはJetstrapで作成したので、htmlのソースを見ると実体はBootstrapが適用されています。紛らわしくてすいません。。)

Foundationのカスタマイズ

Gridで基本的なレイアウトを作成したら、marginなどの微調整や配色にとりかかります。Sass版のFoundationでは配色やフォントサイズ等が変数化されているため、これらの変数に適当な値をセットすることで容易にカスタマイズが可能です。今回は、基本はこれらの変数を使ってカスタマイズをし、適当な変数が用意されていない部分に関しては独自でcss(scss)を書く、というアプローチを取りました。

Foundationで定義されている変数は、Sass版Foundationのディレクトリ(foundation/scss/foundation/)の中にある_settings.scssにデフォルト値とともに記載されているので、これを参考に適当な変数に値をセットしていきます。定義はすべてコメントアウトされているので、_settings.scsssource/stylesheets下などにコピーし、カスタマイズしたい箇所の行のコメントを外す&適当な値をセットしていく、というやり方が簡単でよいかと思います。

_settings.scssと同じfoundation/scss/foundation/の中にある_functions.scssも同じくsource/stylesheetsにコピーして, 以下のように_settings.scss_functions.scssをインポートしておくと、pxremに変換してくれるrem-calc()などの関数が使えるようになって便利です。

@import "functions";

当サイトでは以下の変数を設定しました。bodyの背景色や、topbarの背景色、フォントサイズ、ホバー時のテキスト色などをカスタマイズしています。

$rem-base: 16px;
$body-bg: #ecf0f1;
$primary-color: #386a60;
$panel-bg: #1abc9c;
$panel-border-style: none;
$topbar-bg-color: #34495e;
$topbar-bg: $topbar-bg-color;
$topbar-margin-bottom: rem-calc(20);
$topbar-title-font-size: rem-calc(18);
$topbar-dropdown-bg: $topbar-bg-color;
$topbar-link-color-hover: #1abc9c;
$topbar-link-font-size: rem-calc(24);
$topbar-link-bg-hover: $topbar-bg-color;
$topbar-menu-icon-color-toggled: $topbar-bg-color;

アセットパイプライン

Foundationとその依存ライブラリ、および独自に追加したjavascriptやcssファイルはアセットパイプライン、またはSassの@importを使ってファイルを連結します。

javascript

javascriptはsource/javascriptディレクトリに配置します。必要なjavascriptのライブラリはBowerでvendor/bower_componentsディレクトリにインストール済みなので、source/javascriptにはこれらのライブラリを読み込むための定義を書いたファイルを用意すればOKです。

Foundationの公式サンプルを見ると、modernizr.js<head>要素内で、FoundationとjQueryについては<body>要素の末尾で読み込むにようなっていたので、これに倣ってmodernizr.jsを読み込むためのmodernizr_wrapper.jsと、FoundationとjQueryを読み込むためのapplication.jsの2つのファイルを用意しました。

javascript
├── application.js
└── modernizr_wrapper.js

javascriptを読み込むには//= require <javascriptファイルパス>を使います。例えばfoundation.jsを読み込む場合は//= require vendor/bower_components/foundation/js/foundation.jsと書けばOKですが、今回はvendor/bower_componentsディレクトリをアセットパスに追加しているので、ディレクトリ名は省略できます。またファイルの拡張子(.js)は自動的に補完されるので、//= require foundationとだけ記述すればOKです。

application.jsは以下のように書きました。

//= require jquery
//= require foundation

$(document).foundation();

FoundationはjQueryに依存しているので、jquery.js, foundation.jsの順番で読み込ませています。最後の$(document).foundation();はFoundationを初期化するためのコードです。これが無いとFoundationのjavascriptが動作しません。

modernizr_wrapper.jsでは、vendor/bower_components以下のmodernizr.jsだけを読み込んでいます。

//= require modernizr/modernizr.js

modernizrのディレクトリにはBowerの設定ファイルbower.jsonが含まれていなので、//= require modernizrようにライブラリ名だけを指定した場合middlemanが正しくmodernizr.jsを読み込んでくれません。対策として今回はファイル名を明示的に指定しました。

css

今回はcssはSass(SCSS)を使って書きました。scssファイルはsource/stylesheetsディレクトリに配置します。ディレクトリやファイル構成はMVCSSに倣って作成しました。

ディレクトリ名 ファイル名 用途
core サイト全体で共通するスタイルの定義
_base.scss bodypなどの基本的な要素に対するスタイル定義
_contents.scss タイプグラフィに関するスタイル定義
_helpers.scss functionやmixinの定義
_layout.scss marginやpaddingなどレイアウトに関するスタイル定義
_reset.scss cssリセットの定義
_settings.scss フォントや変数の定義
modules ボタンやモーダルなどの個別コンポーネントのスタイル定義
stylesheets
├── application.css.scss
├── core
│   ├── _base.scss
│   ├── _contents.scss
│   ├── _helpers.scss
│   ├── _layout.scss
│   ├── _reset.scss
│   └── _settings.scss
└── modules

上述のjavascriptと同様にapplication.css.scsscoreおよびmodulesディレクトリ下のファイルと、Foundation等のライブラリのファイルを読み込んで連結しています。coremodules以下のscssファイルは個別のcssにコンパイルする必要がないのでファイル名の先頭に_(アンダースコア)をつけてパーシャルファイルにしています。 application.css.scssはcssにコンパイルすべきファイルであることを明示するために拡張子に.cssをつけています。(.scssだけでもcssファイルにコンパイルされるので、あくまでも見た目でのわかり易さのためにこうしています。)

application.css.scssの中身は以下のようになっています。

@import "compass";
@import "core/reset";
@import "core/helpers";
@import "core/settings";
@import "foundation";
@import "font-awesome";
@import "core/base";
@import "core/layout";

ファイルの読み込みはjavascriptと同様にSprocketsの機能を使って/*= require foundation */と書くこともできますが、Sassの@importでも同じことができます。後者はSprocketsに依存しない方式なので、middleman以外の環境でも使えるという意味でより汎用性が高い書き方と言えると思います。なお、@importでパーシャルを読み込む場合はファイル名の_(アンダースコア)は省略できます。

layout.erbからの読み込み

javascript_include_tagstylesheet_link_tagヘルパを使うと、javascriptとcssを読み込むための<script>タグと<link>タグを簡単に生成できます。<head>タグ内でmodernizr_wrapper.jsapplication.css.scssを、 <body>タグ内でapplication.jsを読み込みます。

<html>
<head>
  <%= stylesheet_link_tag 'application' %>
  <%= javascript_include_tag 'modernizr_wrapper' %>
</head>
<body>
 <!-- bodyタグの末尾に追加 -->
 <%= javascript_include_tag 'application' %>
</body>
</html>

パーシャル

middlemanでは複数のレイアウトを用意してページ毎にレイアウトを切り替えることもできます。その場合はヘッダやフッタなどの共通部分をパーシャルという形で切り出して部品化しておくと、その部品をレイアウト間で使いまわせるので便利です。またhtmlをほどよくパーシャル化して分割しておくとコードの見通しもよくなります。

ヘッダ部分をパーシャル化する例を挙げます。以下のようなヘッダ用のパーシャルを_header.erbとして用意します。(Sassと同様、ファイル名の先頭に_(アンダースコア)をつけます。)

<header>
  <h1>My Blog</h1>
  <h2>A weblog about...</h2>
</header>

レイアウトファイルからは<%= partial "header" %>でこのパーシャルを読み込みます。

<html>
<head>
</head>
<body>
  <!-- headerパーシャルを読み込み -->
  <%= partial "header" %>
</body>
</html>

本サイトではヘッダ、フッタ、ナビゲーションバー、サイドバー、最近の投稿一覧、タグ一覧などのhtmlをパーシャル化しました。

Blog記事のレイアウト

config.rbblog.layout = "blog_post"と設定しているので、layoutsディレクトリにblog_post.erbを用意しておけばその内容がBlog記事ページのレイアウトになります。サイト共通のレイアウトとは異なるレイアウトを適用することもできますが、今回はwrap_layoutを使ってレイアウトを入れ子にし、ヘッダー、フッター、ナビゲーションバーやサイドバーなどの外枠ははそのまま使いつつ、mainの部分にコメントボックスと前後の記事へのリンクを追加する形にしました。

一部簡略化していますが、Blog記事用のレイアウトは以下のようになっています。

<% wrap_layout :layout do %>
  <!-- Blog記事本文 -->
  <%= yield %>
  <!-- comment box -->
  <div class="row">
    <div class="small-12 columns"></div>
  </div>
  <!-- article pager -->
  <div class="row">
    <div class="small-4 columns">previous page</div>
    <div class="small-4 columns">home</div>
    <div class="small-4 columns">next page</div>
  </div>
<% end %>

<%= yield %>から<% end %>の手前の</div>までがBlog記事のレイアウトになります。<%= yield %>にはBlog記事の本文が挿入されて、その下にコメントボックスと前後の記事へのリンク、という形となります。これを<% wrap_layout :layout do %> ... <% end %>で覆っているので、このBlog記事が更にサイト共通のレイアウト(layout.erb)で囲まれる形となります。

最終的にBlog記事のレイアウトは以下のようになります。

<html>
<head></head>
<body>
  <!-- header -->
  <div class="row">
    <div class="small-12 columns show-for-medium-up"></div>
  </div>
  <!-- top bar(navbar) -->
  <div class="row">
    <div class="small-12 columns"></div>
  </div>
  <!-- contents -->
  <div class="row">
    <!-- main -->
    <div class="small-12 large-9 columns"></div>
    <!-- Blog記事本文 -->
    <%= yield %>
    <!-- comment box -->
    <div class="row">
      <div class="small-12 columns"></div>
    </div>
    <!-- article pager -->
    <div class="row">
      <div class="small-4 columns">previous page</div>
      <div class="small-4 columns">home</div>
      <div class="small-4 columns">next page</div>
    </div>
    <!-- sidebar -->
    <div class="small-12 large-3 columns"></div>
  </div>
  <!-- footer -->
  <div class="row">
    <div class="small-12 columns"></div>
  </div>
</body>
</html>

html(erb) -> hamlへの変換

前半にも書きましたが、本サイトはerbではなくHaml使って書いています。middlemanのblog拡張のスケルトンに含まれるテンプレートはerbで書かれているので、このテンプレートを使いたい場合はerbをhamlへ変換する必要があります。またBootstrapのテンプレートなどをベースにする場合は同じようにhtmlをhamlに変換する必要があります。

手動で変換してもよいですが、html2hamlというgemを使うと変換が簡単に実行できます。

html2haml インストール

まずはgemをインストールします。Gemfilegem html2hamlを追記して、bundle installを実行します。

source 'http://rubygems.org'

gem "middleman", "~> 3.2.1"
gem "middleman-blog", "~> 3.5.1"
gem "middleman-livereload"
gem "nokogiri"
gem "redcarpet"
gem "html2haml" # 追加

# For feed.xml.builder
gem "builder", "~> 3.0"
$ bundle install

hamlへの変換

html(erb)をhamlへ変換するにはhtml2haml <html(erb)ファイル名> <hamlファイル名>を実行します。例えばindex.html.erbをhamlに変換する場合はsourceディレクトリで以下をコマンド実行します。

$ bundle exec html2haml index.html.erb index.html.haml

これでsourceディレクトリに変換後のindex.html.hamlが生成されます。ただし100%正確に変換が行われるとは限らないので、手動で修正が必要となる場合もあります。また変換後も元のhtml(erb)ファイルは残ったままなので、変換完了後に手動で削除する必要があります。

hamlでの書き方を知りたい場合など、ファイル全体ではなくhtml(erb)の一部を変換したい場合もあるかと思います。この場合はHTML2HamlというWebサービスが便利です。html(erb)のコードを貼り付けると、対応するhamlのコードを表示してくれます。hamlに慣れないうちは重宝します。

その他

Foundation5はIE8以下には対応していません。一応ワークアラウンドは存在しますが、完全な対策ではありません。IE8対応が必須の場合はFoundation3など、IE8対応のフレームワークを使用する方が良いかと思います。

まとめ

Foundationの使い方は公式ドキュメントと、公式サイトのダウンロードファイルに同梱されているサンプルhmtl見ると基本的な使い方は掴めると思います。 またgithubに今回までの内容を含んだソースコードをアップしましたので、本記事で書ききれなかったレイアウトやcssの細かい部分はこちらを参照いただければと思います。

今回までの内容でBlogサイトの基本部分は完成しましたが、コメント欄や検索機能、コードを載せるならシンタックスハイライト機能も付けたいところです。次回はこれらの追加方法について書きたいと思います。

参考サイト

comments powered by Disqus