#334 Compass & CSS Sprites
- Download:
- source codeProject Files in Zip (102 KB)
- mp4Full Size H.264 Video (33.2 MB)
- m4vSmaller H.264 Video (14.2 MB)
- webmFull Size VP8 Video (14.2 MB)
- ogvFull Size Theora Video (36.1 MB)
Compassは、便利なmixinや関数などによって、SASSでのスタイルシートの生成をより簡単にしてくれます。新しいCompassRails gemを利用すれば、Railsのasset pipelineへの統合が今まで以上に簡単になります。下の図は、Railscastsのサイトデザインの簡略版です。これからCompassを使って、このアプリケーションの見た目は変えないままで、基となるスタイルを改善していきます。
RailsアプリケーションにCompassを追加するには、gemfileのassets
グループにCompassRails gemを追加してからbundle
コマンドを実行します。
# 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 'compass-rails' end gem 'jquery-rails'
次にapplication.css
のファイル名をapplication.css.scss
に変更します。これによってファイルはSASSで解釈されるようになり、そうすることでCompassをロードする場所ができ、アプリケーション内の全てのSASSファイルから利用できるようになります。Sprocketsではこの機能を利用できないので、このファイルからmanifestを削除し、その代わりにSASSを使用して必要なファイルをインポートします。アプリケーションにはlayout.css.scss
というファイルがあるので、compass
ファイルとともにそれもインポートします。
@import "compass"; @import "layout";
アプリケーションにgemを追加したので、サーバを再起動します。その後にページをリロードすると、ページは前のままです。ただ違うのは、SASSのコードを改善するためにCompassを使うことができるという点です。
アプリケーションでCompassを使用する
アプリケーションにcompass
ファイルを追加すると、Compassの新しい機能を利用できるようになります。Compassを使うとCSS3を簡単に扱うことができ、ブラウザごとのprefixを指定しなくてもグラデーションやボックスシャドーや角の丸みなどのCSS機能を使うことができます。対象のRailscastsアプリケーションはグラデーションを使用していて、imagesセクションにそれについてのドキュメントがあります。Compassを使用してナビゲーションバーのコードを改善します。このスタイルはレイアウトファイルで処理されています。
#nav_bar { position: relative; padding: 8px 100px; margin-bottom: 15px; border-top: solid 1px #FFF; border-bottom: solid 3px #DE9F00; background-color: #333; background-image: -webkit-linear-gradient(#5c5c5c, #111111); background-image: -moz-linear-gradient(#5c5c5c, #111111); background-image: -ms-linear-gradient(#5c5c5c, #111111); background-image: linear-gradient(#5c5c5c, #111111); .nav { float: right; padding-top: 2px; li { padding-left: 25px; font-size: 14px; color: #BBB; a { color: #FFF; } } } }
このファイルでは各種のブラウザに対応させるためにグラデーションを4回定義しています。Compassを使えばその必要はありません。1行のコードで処理できます。
@include background-image(linear-gradient(#5c5c5c, #111111));
これによって各種ブラウザ用の指定を自動的に生成します。ページをリロードすると見た目はそのままですが、生成されたCSSを見るとCompassがグラデーションを設定しているのがわかります。
/* line 69, ../../app/assets/stylesheets/layout.css.scss */ #nav_bar { position: relative; padding: 8px 100px; margin-bottom: 15px; border-top: solid 1px #FFF; border-bottom: solid 3px #DE9F00; background-color: #333; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #5c5c5c), color-stop(100%, #111111)); background-image: -webkit-linear-gradient(#5c5c5c, #111111); background-image: -moz-linear-gradient(#5c5c5c, #111111); background-image: -o-linear-gradient(#5c5c5c, #111111); background-image: -ms-linear-gradient(#5c5c5c, #111111); background-image: linear-gradient(#5c5c5c, #111111); }
CSSスプライトを使う
Compassに求めることがCSS3の機能を簡単に利用できることだけであれば、エピソード330で紹介したBourbonを代わりに使うこともできます。Compassが提供する機能はそれだけにとどまらず、その中にはCSSスプライトも含まれます。CSSスプライトとは、いくつかの小さな画像を結合して1つの大きな画像にした上でCSSを使って個別の画像を表示させる手法です。今回のページでは、Railscastsを購読するためのいくつかの方法を示す一連のアイコンがあります。これらのアイコンはそれぞれに画像を持ち、それらを表示するためには個別のHTTPリクエストを発行することになります。ページから発行されるリクエストはなるべく少なくするほうがいいでしょう。これらのアイコンを一つのファイルに結合できれば、CSSを使ってその画像の選択された一部を各アイコンとして表示できます。
CSSスプライトを手作業で設定するのは手間がかかりますが、Compassを使えば簡単です。アイコンは現在background-image
への呼び出しで処理されています。
#subscribe { position: absolute; bottom: 10px; right: 100px; li { position: relative; margin-left: 8px; font-size: 12px; } a { display: block; width: 34px; height: 34px; } .itunes { background-image: image-url("icons/itunes.png"); } .twitter { background-image: image-url("icons/twitter.png"); } .facebook { background-image: image-url("icons/facebook.png"); } .rss { background-image: image-url("icons/rss.png"); } }
Compassのスプライトを利用するために、まず必要な画像をすべて集めて同じディレクトリに入れます。今回の場合はすでに/app/assets/images/icons
にまとまっているので、この作業は必要ありません。@import
でパスを指定して画像をCompassにロードします。
@import "icons/*.png";
これによってそのディレクトリにある画像がすべて読み込まれ、一つのスプライト画像が作成されます。これを利用する方法はいくつかあります。より手作業に頼ったアプローチは、各アイコンを表示させるときのbackground-image
の呼び出しを置き換える方法です。
.itunes { @include icons-sprite(itunes); } .twitter { @include icons-sprite(twitter); } .facebook { @include icons-sprite(facebook); } .rss { @include icons-sprite(rss) }
ページをリロードすると、今回も見た目は変わりませんが、アイコンはすべて一つの画像にまとめられたので、1回のリクエストでそれらがすべてダウンロードされます。
Compassはこれをさらに簡単に行う方法も提供します。スプライトを個別のCSSクラスにロードする代わりに、それらをすべてCompassを介しておこなうこともできます。各アイコンを示す4つのクラスのためのCSSを削除して、以下と入れ替えます。
@import "icons/*.png"; @include all-icons-sprites;
これにより各画像用のそれぞれのCSSクラスが自動的に作成されます。それらを参照するようにHTMLを修正します。各アイコンは以下のようにリストとして表示されます。
<ul id="subscribe" class="horizontal"> <li><a class="itunes" href="/itunes"></a></li> <li><a class="twitter" href="/twitter"></a></li> <li><a class="facebook" href="/facebook"></a></li> <li><a class="rss" href="/rss"></a></li> </ul>
後は各クラスの前にディレクトリ名(今回の場合はicons
)とダッシュを付けます。
<ul id="subscribe" class="horizontal"> <li><a class="icons-itunes" href="/itunes"></a></li> <li><a class="icons-twitter" href="/twitter"></a></li> <li><a class="icons-facebook" href="/facebook"></a></li> <li><a class="icons-rss" href="/rss"></a></li> </ul>
ページの見た目は変わらないままですが、生成されたCSSは一つの画像を参照し、background-position
を使って各アイコン用に対応する部分が表示されています。
/* line 66, icons/*.png */ .icons-sprite, .icons-facebook, .icons-itunes, .icons-rss, .icons-twitter { background: url(/assets/icons-s1286bd1660.png) no-repeat; } /* line 60, ../../../.rvm/gems/ruby-1.9.3-p125/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/utilities/sprites/_base.scss */ .icons-facebook { background-position: 0 -102px; }
スプライトについては“Spriting With Compass”チュートリアルにさらに情報があります。
シンプルな水平リスト
Compassのドキュメントはすべてわかりやすく書かれているので、時間をかけてReferenceとHelpのセクションに目を通してCompassのその他の機能を理解しておくことをお勧めします。多くのユーティリティ関数があり、その中の一つを使うと水平リストを簡単に作ることができます。ナビゲーションメニューを出力するためにはリストがよく使われますが、これはhorizontal-list
mixinを使えば簡単です。Railscastsサイトにはまさにそれをおこなう.horizontal
というCSSクラスがあり、そのSASSコードは以下のようになります。
ul.horizontal { list-style: none; margin: 0; padding: 0; li { margin: 0; padding: 0; float: left; } }
これをそのmixinの呼び出しに置き換えることができます。
ul.horizontal { @include horizontal-list; }
ページ上のそれぞれの水平リストは元のままの形で出力されますが、それぞれmarginかpaddingを少し調節する必要があります。
Compass Reset
Compass Resetはもう一つの便利な機能です。ブラウザによって、要素間のサイズやスペースのデフォルト値は異なります。Compass Resetを使ってすべての設定をゼロにすることで、ブラウザが違ってもスタイルに一貫性を持たせることができます。使用するにはapplication.css.scss
ファイルでインポートします。
@import "compass"; @import "compass/reset"; @import "layout";
これは、レイアウトにCSSを挿入する数少ないcompassコマンドの一つなので、使用する場合はそれを意識しておく必要があります。これを設定すると、h1
要素の中の“Welcome”の文字列はずっと小さくなりました。
大抵のサイトはReset CSSが追加された後にデザインが崩れますが、これはほとんどのサイトのデザインが何らかブラウザのデフォルトのスタイルに依存しているからです。しかしResetを設定すれば、複数のブラウザ間でも一貫したスタイルを持つことができます。例えば、h1
要素をどう出力したいかというようなことを個別に宣言することができます。
h1 { font-size: 28px; font-weight: bold; margin: 18px 0; }
ページは以前と同じように表示されます。
CSS Resetはいつもうまくいく訳ではありませんが、ブラウザ間でのデザインの一貫性を重視する場合は利用を検討する価値があるでしょう。Compass Resetの代替としてはnormalize.cssを参照してください。こちらはブラウザのデフォルトに近い値をデフォルトとして設定するので、すべての要素を最初から設定し直す必要がありません。
参考情報
今回のエピソードは以上です。ここで触れられなかった機能もいくつかあるので、ウェブサイトの方も参照してください。触れることができなかったCompassのパーツの一つがblueprintモジュールです。これはグリッドベースのデザインを構築するためのCSSフレームワークの一式です。またCompassをRailsに統合するための別のアプローチを知るために、CompassRailsのREADMEを読むことをお勧めします。Railsの古いバージョンを使用している場合、そこにCompassRailsを利用できるようにするために役に立つ情報があります。
Compassは大規模なフレームワークですがモジュール構成になっているので、自分のアプリケーションに必要なパーツだけをインクルードして利用することが可能です。