#328 Twitter Bootstrap Basics
- Download:
- source codeProject Files in Zip (52.1 KB)
- mp4Full Size H.264 Video (32.3 MB)
- m4vSmaller H.264 Video (14.4 MB)
- webmFull Size VP8 Video (14.4 MB)
- ogvFull Size Theora Video (35.7 MB)
Twitter Bootstrapを使えば、美しいWebアプリケーションをすばやく作成することができます。レイアウト、ナビゲーション、フォーム、その他を作成するための多くの種類のCSSとJavaScriptを提供し、レスポンシブ・ウェブデザインもサポートしています。例として、ホームページにアクセスしてブラウザウィンドウの幅を変えると、ページレイアウトはその幅にもっとも適した形に変化します。これによってモバイルデバイスでウェブアプリケーションを利用するときの使い勝手が大きく改善されます。
Twitter Bootstrapのウェブサイトをいろいろ見てその機能をすべて理解することをお勧めしますが、今回のエピソードでは特にRailsアプリケーションと一緒に利用する方法を紹介します。一つの選択肢としては、“Download Bootstrap”ボタンをクリックして静的なCSSとJavaScriptのファイルをダウンロードして、/app/assets
ディレクトリの適切な場所にファイルを移動するという方法があります。しかしRailsを使っているのであれば、これはベストのアプローチではありません。Twitter BootstrapはLESSを使って書かれています。LESSはCSSプリプロセッサで、Railsで採用されているSASSにとても似ています。
Twitter Bootstrapをもっとも柔軟に使うためには、LESSのような動的な言語とともに使用する方が、そこから出力されたコンパイルされた静的ファイルを使うよりもいいでしょう。Railsと一緒にLESSを動作させるためにはRuby gemの助けが必要です。RailsにBootstrapを統合するためのgemはいくつかあります。今回のエピソードではtwitter-bootstrap-rails gemを使うことにしますが、後ほどその他の選択肢についても少し触れます。このgemを選択した理由は、LESSを直接扱えるという点と、簡単に利用するためのジェネレータが提供されているという点です。話を少し急ぎすぎてしまったので、まずは対象とするRailsアプリケーションを準備していきます。
新規のRailsアプリケーションにBootstrapを追加する
まずstore
という名前の新規のアプリケーションを作り、作業をおこなう対象とするProduct
モデルをscaffoldで生成します。
$ rails new store $ cd store $ rails g scaffold product name price:decimal --skip-stylesheets $ rake db:migrate
scaffoldコマンドで--skip-stylesheets
オプションを使用していることに留意してください。これはscaffoldで生成されるCSSの代わりにBootstrapのCSSを使用するためです。次にデータベースのマイグレーションをおこなってproductsテーブルを作成します。scaffoldで生成されたページは次のとおりです。まだスタイルを何も指定していないため、見た目はあまりきれいではありません。それではTwitter Bootstrapを追加していきます。
まず最初のステップとして、gemfileのassets
グループにtwitter-bootstrap-rails
gemを追加します。このgemはassets pipelineのみで利用されるため、このグループだけで使用されます。本番環境で静的assetを使用するのであれば必要ありません。
# Gems used only for assets and not required # in production environments by default. group :assets do gem 'sass-rails', '~> 3.2.3' gem 'coffee-rails', '~> 3.2.1' # See https://github.com/sstephenson/execjs#readme for more supported runtimes # gem 'therubyracer' gem 'uglifier', '>= 1.0.3' gem 'twitter-bootstrap-rails' end
次にbundle
コマンドを実行して、twitter-bootstrap-rails
とその依存関係をインストールします。このgemは、libv8
やless-rails
を含むいくつかの依存関係を持っており、これらによってアプリケーションがLESSの文法を解釈できるようになります。これでBootstrapがインストールされたので、ジェネレータを実行してインストールをおこないます。
$ rails g bootstrap:install insert app/assets/javascripts/application.js create app/assets/javascripts/bootstrap.js.coffee create app/assets/stylesheets/bootstrap_and_overrides.css.less gsub app/assets/stylesheets/application.css gsub app/assets/stylesheets/application.css
これによってBootstrapが/app/assets
ディレクトリ内に設定されます。生成されたファイルのうちキーとなるのはbootstrap_and_overrides.css.less
です。このファイルがBootstrapを読み込みますが、アプリケーションに合うようにスタイルをカスタマイズするのであればここに対しておこなうのがいいでしょう。サーバを再起動してページを読み込み直すと、もうすでにスタイルがきれいに変わっていますが、まだまだ作業が必要です。
レイアウトを改良する
まずアプリケーションのレイアウトに注力します。twitter-bootstrap-rails
gemのbootstrap:layout
ジェネレータでレイアウトファイルを生成することもできますが、ここではその方法は使いません。その代わりにレイアウトを変更するために必要な作業を順番に見ていくことによって、Twitter Bootstrapがどういう仕組みで動くのかを理解するためのヒントを示します。
レイアウトにはfixedとfluidの2種類があります。fixedレイアウトは横幅のピクセル数が固定で、fluidレイアウトはブラウザの幅に合わせて横に広がります。ラッパーのdiv
のクラスをcontainer
かcontainer-fluid
と指定することで、どちらのレイアウトが使われるかが決定されます。ここでは固定幅のレイアウトを使うため、レイアウトファイルのbody
にcontainer
クラスのdiv
を追加します。
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>Store</title> <%= stylesheet_link_tag "application", :media => "all" %> <%= javascript_include_tag "application" %> <%= csrf_meta_tags %> </head> <body> <div class="container"> <%= yield %> </div> </body> </html>
Twitter Bootstrapは12カラムのグリッドシステムを使用します。これによって、各カラムの幅を指定することで、簡単にカラムベースのレイアウトデザインを適用できます。このレイアウトはレスポンシブなので、ブラウザの幅を小さくするとそれに従ってレイアウトが変化します。例えばサイドバーを付けることにして、それをページ幅の25%にしたいとしましょう。これは次のようにレイアウトファイルを修正することで設定できます。とりあえず適当な固定のテキストをサイドバーに追加します。
<div class="container"> <div class="row"> <div class="span9"><%= yield %></div> <div class="span3"> <h2>About Us</h2> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> </div> </div> </div>
ここでページをリロードすると新しい2カラムのレイアウトが表示されます。
ナビゲーションバーを追加する
次にページの最上部に、サイト内を移動するリンクがついたナビゲーションバーを追加します。ドキュメントのcomponents(部品)セクションに、navbar(ナビゲーションバー)を含むTwitter Bootstrapが提供するさまざまな種類のナビゲーションのオプションについての説明があります。このナビゲーションバーを目的に合うようにカスタマイズして、リンク、ドロップダウン、検索フィールドなどを追加できます。ドキュメントにはそれぞれの項目を追加する場合のいろいろなサンプルが含まれています。レイアウトページの最上部にナビゲーションバーを追加します。
<div class="navbar navbar-fixed-top"> <div class="navbar-inner"> <div class="container"> <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </a> <a class="brand" href="#">Some Store</a> <div class="nav-collapse"> <ul class="nav"> <li><%= link_to "Browse Products", products_path %></li> <li><%= link_to "Price List" %></li> <li><%= link_to "Contact Us" %></li> <li><%= link_to "Cart" %></li> </ul> </div> </div> </div> </div>
ナビゲーションにはブランド名のセクションとダミーのリンクが含まれています。最上部のセクションが興味をひきます。ブラウザの幅が変わったときにナビゲーション部が折り畳まれる処理をおこなっています。ページをリロードすると新しいナビゲーションバーが表示されます。
折り畳まれたバージョンのナビゲーションが表示されていることに留意してください。これは、ブラウザウィンドウの幅が800ピクセルに設定されていて、フルバージョンを表示するには幅が足りないからです。ウィンドウの幅を広げると隠れていたナビゲーションが現れます。
しかしこれをおこなうと問題が発生します。ページの上部がナビゲーションバーで隠れてしまいます。これはnavbarをfixedで使用する場合の副作用で、ドキュメントを見るとこの望ましくない効果を避けるには、body
要素の一番上のBootstrap CSSとレスポンシブCSSの間に少なくとも40ピクセルのpadding(余白)を追加します。これをbootstrap_and_overrides.css
ファイルに記述します。このファイルはbootstrap
とresponsive
ファイルをincludeしていて、ドキュメントによるとpaddingはこれらの間に追加します。
@import "twitter/bootstrap/bootstrap"; body { padding-top: 60px; } @import "twitter/bootstrap/responsive"; // Set the correct sprite paths @iconSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings.png'); @iconWhiteSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings-white.png'); // Your custom LESS stylesheets goes here // // Since bootstrap was imported above you have access to its mixins which // you may use and inherit here // // If you'd like to override bootstrap's own variables, you can do so here as well // See http://twitter.github.com/bootstrap/less.html for their names and documentation // // Example: // @linkColor: #ff0000;
ページをリロードすると、ページの最上部はもうナビゲーションバーの後ろに隠れていません。
Headerに仕上げの微調整をおこなう
アプリケーションのレイアウトファイルはほぼ完成しましたが、どこでも動作するようにheadセクションに少し追加をします。
<head> <title>Store</title> <!--[if lt IE 9]> <script src="http://html5shim.googlecode.com/svn/trunk/html5.js" type="text/javascript"></script> <![endif]--> <%= stylesheet_link_tag "application", :media => "all" %> <%= javascript_include_tag "application" %> <%= csrf_meta_tags %> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head>
ここに追加したコードの最初の部分は、Internet Explorerの古いバージョンでのHTML 5サポートを改善します。次の行はviewport meta
タグで、これがモバイルデバイスにおけるレスポンシブデザインの振る舞いを修正します。
ビューを改良する
このアプリケーションの他のビューはどうすればいいでしょうか? scaffoldで生成された現在のコードの外観を改善するためにTwitter Bootstrapができることはたくさんあります。その前にまず作業をおこなう対象として何件か商品レコードを追加します。
次にTwitter Bootstrapを使ってこのページの外観を改善します。一つずつ手で修正する代わりに、gemが提供するジェネレータを利用します。このジェネレータはthemed
と呼ばれてscaffoldと合わせて動作するので、使用するときはscaffoldの名前を渡します。同じく-f
オプションを指定することで、生成されたビューファイルを強制的に上書きします。
$ rails g bootstrap:themed products -f
商品ページをリロードすると、ずっときれいになっています。表は前よりもずっときれいになり、“edit”と“destroy”のリンクは通常のテキストのリンクではなくボタンになりました。
同じような変更が、個別の商品の表示用と編集用のページにも適用されました。これらのテンプレートのソースを見ることで、しくみを理解することができます。
<h1>Products</h1> <table class="table table-striped"> <thead> <tr> <th>ID</th> <th>Name</th> <th>Created at</th> <th>Actions</th> </tr> </thead> <tbody> <% @products.each do |product| %> <tr> <td><%= product.id %></td> <td><%= link_to product.name, product_path(product) %></td> <td><%= product.created_at %></td> <td> <%= link_to 'Edit', edit_product_path(product), :class => 'btn btn-mini' %> <%= link_to 'Destroy', product_path(product), :method => :delete, :confirm => 'Are you sure?', :class => 'btn btn-mini btn-danger' %> </td> </tr> <% end %> </tbody> </table> <%= link_to 'New', new_product_path, :class => 'btn btn-primary' %>
商品を表示する表にいくつかのCSSクラスが追加されました。同じように“Edit”と“Destroy”にもクラスが追加され、見た目がきれいになりました。最も大きな変更箇所は、個別の商品の新規作成および編集用の部分テンプレートです。
<%= form_for @product, :html => { :class => 'form-horizontal' } do |f| %> <fieldset> <legend><%= controller.action_name.capitalize %> Product</legend> <div class="control-group"> <%= f.label :name, :class => 'control-label' %> <div class="controls"> <%= f.text_field :name, :class => 'text_field' %> </div> </div> <div class="control-group"> <%= f.label :price, :class => 'control-label' %> <div class="controls"> <%= f.text_field :price, :class => 'text_field' %> </div> </div> <div class="form-actions"> <%= f.submit nil, :class => 'btn btn-primary' %> <%= link_to 'Cancel', products_path, :class => 'btn' %> </div> </fieldset> <% end %>
このコードはscaffoldで生成されたものから大きく変わっていて、Twitter Bootstrapでフォームの外観をとてもきれいにできるいいサンプルになるでしょう。
このエピソードも終わりに近づいてきたので、予告した通りtwitter-bootstrap-rails gemの代替についても触れておきます。Ruby Sourceのこの記事にそれらのリストがあり、Twitter Bootstrapのしくみとさまざまなオプション、そしてRailsに統合するために利用できるgemについての説明があります。