この記事は、http://css-tricks.com/ の Chris Coyier の許可を得て、一部変更し、翻訳しています。オリジナルの記事はここよりご覧いただけます。

この記事は元々2007年の後半にVolkan Görgülüと共同執筆したものですが、今回加筆修正致しました。

CSS Sprites使い方

本当に「知っている」と言えますか?まず、その名前だけ聞くと、ちょっと誤解を招くかもしれません。なぜならここで言うSpritesは、あなたが今思い浮かべているであろう小さい画像のことではなく、もっと大きな1つの画像のことを差しているからです。今までにオンとオフの状態が同じ画像に含まれていて、バックグラウンドの位置を変更することにより、画像表示が切り替わるようなCSSのテクニックを見たことがありますか?

simple css sprite jp ウェブの常識:CSS Sprite(スプライト)とは?

こちらにそのCSSのトリックの一例があります。
CSSスプライトもその延長上にあると考えてみましょう。相違点はと言うと、前述のCSSテクニックの場合は2つか3つの画像が1つの画像にまとめられている程度ですが、CSSスプライトの場合は何十個何百個と無制限の画像を1つにまとめることが可能です。「スプライト」という言葉の語源はもうかなり昔のコンピュータグラフィックとビデオゲーム産業に由来します。そのアイデアはコンピュータがグラフィックをメモリに取得することであり、その画像の一部分のみを表示させます。この方が次々に新しい画像を取得するよりも速いのです。スプライトは大きな複合グラフィックです。CSSスプライトはこれと殆ど同じ理論を使っています:まず画像を取り出して、シフトすることにより一部分のみを表示させ、複数の画像を取得することにより発生するオーバーヘッド(システム全体の負荷)を軽減させます。

Spriteでウェブパフォマンスの向上

いいえ、そんなことはありません。もう大分過去のことになりますが、昔はみんなページのロードスピードを速くするために画像を小さく分割していました。そういった技術は分割された画像が同時にロードされてくるので、スピードが短縮されたかのように感じられました。けれど全ての画像は1つ1つ異なるHTTPリクエストとして送信されるのであんまり効率的とは言えないかと思います。
Tenni TheurerさんがYahoo!のユーザーインターフェースブログに掲載した”Performance Research, Part 1: What the 80/20 Rule Tells Us about Reducing HTTP Requests(パフォーマンスリサーチ Part1:HTTPリクエストを減らす80/20ルールとは?”という記事を参照してみましょう。
テーブル1はHTMLドキュメントのダウンロードに5%から38%ほどを必要とするWEBサイトの一覧です。残りの62%から95%は画像やスクリプトやスタイルシートと言ったHTMLドキュメント内のその他のコンポーネントを取得するためのHTTPリクエストとして使われています。HTTPバージョンのレスポンスの速さや各ユーザーのブラウザにより異なりますが、ページ上に沢山のコンポーネントを保有していることは、ブラウザがホスト名ごとに並行してたったの2つか4つのコンポーネントしかダウンロードしないという事実によりさらに悪い影響を与えます。こういった経験により、HTTPリクエストの数を減少させることは応答時間の減少にも大きく影響し、またもっとも簡単なパフォーマンスの向上と言えるのではないでしょうか。

テーブル 1 各有名サイトでのローディングに費やす時間比較
HTMLの取得にかかる時間 それ以外
Yahoo! 10% 90%
Google 25% 75%
MySpace 9% 91%
MSN 5% 95%
ebay 5% 95%
Amazon 38% 62%
YouTube 9% 91%
CNN 15% 85%

1つ1つの画像は、例えそれが<img=タグで記述されてようと、CSSで背景画像として記述されていようと、結局は別々のHTTPリクエストです。従ってこういった個々のリクエストがどのような悪影響を及ぼしてくるかは、想像するに容易いかと思います。

CSS Sprite(スプライト)活用方法

それでは、CSSスプライトを使用する前の例から見てみましょうか。下記のCSSでは、それぞれのクラスでは背景画像を指定しているのに対し、アンカータグ自体は背景画像がNONEになっていることに注目してください。

#nav li a {background:none no-repeat left center}
#nav li a.item1 {background-image:url('../img/image1.gif')}
#nav li a:hover.item1 {background-image:url('../img/image1_over.gif')}
#nav li a.item2 {background-image:url('../img/image2.gif')}
#nav li a:hover.item2 {background-image:url('../img/image2_over.gif')}
...

example1before jp ウェブの常識:CSS Sprite(スプライト)とは?

CSSスプライトを使用すれば、もう少しこのデータを軽くすることが出来ます。5つのボタンの為に10個の別々の画像(5つはデフォルト状態の画像で、残りの5つはマウスがロールオーバーした場合の画像)を用いる代わりに、全ての画像を1つにの大きな画像にまとめてしまえばよいのです。あまり細かいところまでは説明しませんが、簡単な流れをお見せしましょう。まず1つの大きな画像を作成してください。横幅は使用する画像の中で一番横幅が広いものに揃え、縦幅は使用する全ての画像の高さ合計プラスXピクセルを加えてください。Xピクセルとはこれからひとまとめにする画像の合計数です。次に左揃えの状態で、画像を1ピクセル間隔空けながら縦に並べてください。

それではCSSスプライト使用後の例を見てみましょう。CSSではアンカー要素自体には1つの背景画像が設定されており、個々のクラスにはY座標で背景画像の位置を変えているだけです。

#nav li a {background-image:url('../img/image_nav.gif')}
#nav li a.item1 {background-position:0px 0px}
#nav li a:hover.item1 {background-position:0px -72px}
#nav li a.item2 {background-position:0px -143px;}
#nav li a:hover.item2 {background-position:0px -215px;}
...

example1after jp ウェブの常識:CSS Sprite(スプライト)とは?

これによりHTTPリクエストの数を9個も減らすことに成功し、画像の合計サイズも6.5KB減少しています。こんな小さなサンプルでもこれだけ大きな数字の変化があるのですから、本物のWEBサイト上ではどれだけ違ってくるのか想像してみてください。

CSS Sprite(スプライト)ツール

Chuck Norriceさんは「大きなことを成し遂げるには、それ相当の大きな貢献をしなければならない」とおっしゃっていたことを思い出しました。本当に彼がおっしゃったかどうかは定かではないのですが、まぁとにかくよいアドバイスだと思いませんか。しかし幸いにもCSSスプライトを簡単に作成し実装出来るようなWEBサービスが存在するのです。本当に数多くのサービスが存在するのですが、中でも私がおススメは、SpriteMeです。

SpriteMeを使ってみましょう

SpriteMeはブックマークレットです。なので一度ブックマークバーに登録してしまえば、あとは好きなWEBサイトに行ってブックマークをクリックすればいいだけです。するとスクリーンの右側にオーバーレイで表示されます。

spriteme 1 ウェブの常識:CSS Sprite(スプライト)とは?

上部の枠は、スプライトで一括出来ると予想される背景画像の一覧です。下の方の枠はスプライトでまとめるには適していないであろうと予想される画像の一覧で、その理由もきちんと表示されています。もしあなたの考えと異なるならば、ドラッグして上や下の一覧に加えたり外したりすることも可能です。上の枠にひとまとめにしたい画像が整ったら、「Make Sprite」のボタンをクリックしてください。自動的に1つの大きな画像にまとめてくれます。(やった!CSSスプライトですね!)ひとまとめになった画像はこんな感じで表示されます。

spriteme 2 ウェブの常識:CSS Sprite(スプライト)とは?

このサイトの現在の設定では、最終結果の(縮小)版です。(よろしければ本物の方も参照してみてくださいね。)

sprite example ウェブの常識:CSS Sprite(スプライト)とは?

最近SpriteMeではCSSをエクスポート出来るようになりました。ボタンをクリックすると以下のようなコートが表示されます。

A id=home-link
{
  background-image: url(http://css-tricks.com/wp-content/themes/CSS-Tricks-4/images/logo.png)
  background-image: url(http://www.jaredhirsch.com/coolrunnings/public_images/3deb155981/spriteme1.png);
  background-position: -10px -10px;
}
A
{
  background-image: url(http://css-tricks.com/wp-content/themes/CSS-Tricks-4/images/nav.png)
  background-image: url(http://www.jaredhirsch.com/coolrunnings/public_images/3deb155981/spriteme1.png);
  background-position: -10px -56px;
}

線で消されたコードは今までCSSで使用していたコードで、そのコードを書き換えたものが直下に記述されています。

それではスプライトで不可能なことは?

グラフィックを繰り返し表示することが出来ません(注1)。スプライトは1つのブロックになったグラフィック用のものです。例えばアイコンなどはCSSスプライトで使用するのにとても適しています。
注1:勿論繰り返し使用することも出来なくはないのですが、ちょっとトリッキーで、X方向かY方向いずれかの1方向にしか使えません。

CSS Sprite(スプライト)実用性

スプライトを使用することにはもう誰も疑いを持たないでしょう。ぜひ使用してみるべきです。それでは新しいデザインを作成する際の、ワークフローはどのようにしましょうか。きっと以下の2つの方法いずれかを使用した方がいいかと思います。まず1つ目は、ページを作るのと同時進行でCSSスプライトも設定していきます。ということは、フォトショップも開いて、左上から順番に画像を並べていきます。また追加したい画像があれば追加して再保存していきます。
もう1つの方法は、、、こちらの方がしっくり来るかと思うのですが、CSSスプライトは後回しに考えます。まずはそれぞれ別々に画像を作成してしまいます。そしてページが完成したら(もしくは、少なくともリリースできる状態になったら・・・。ページっていつまで経っても更新改善要素満載ですからね。)、SpriteMeを使用してスプライトしていけば完成です。

その他の例も少し載せておきますね。

Google Reader icons

1454282699 lhn sprite ウェブの常識:CSS Sprite(スプライト)とは?

Facebook

facebook sprite ウェブの常識:CSS Sprite(スプライト)とは?