現在作業中のサイトでは「CSSスプライト」という手法を使って、アイコンやロゴなどの画像表示の最適化を試みようと思っています。アイコンなどの小さな画像が数多くあると、その分ダウンロードする際にサーバへの接続回数(HTTPリクエスト)が多くなってしまい、ページ表示速度を遅くさせてしまう可能性があります。そこで、CSSスプライトを使った方法では、それら複数の画像を一つにまとめて必要な部分のみをCSSで表示させます。
CSSスプライトの方法にもいろいろあるようですが、ここではGoogleやFacebookが採用しているアイコン画像を縦と横に並べた、よりコンパクトなスプライト画像を使う方法についてまとめてみます。※現段階ではIE6、IE7未対応
CSSスプライトのしくみ
たとえば、Googleのスプライトの「+」アイコンを表示させる場合、以下のような方法をとります:
- アイコンを表示したい部分に<span>などを使用して表示領域の高さと幅をCSSで指定
- CSSで<span>の背景にスプライト画像を指定
- 下図のように背景画像の位置をずらして、表示させたいアイコンを表示させる
CSSスプライトのメリット・デメリット
まだ運営段階に入っていないので、これから分かってくることもあると思いますが、現段階で考えつくメリット・デメリットは以下のとおりです。これを見るとメリットのほうが多そうです。
メリット
複数画像を一つにまとめることで、サーバへの接続回数(HTTPリクエスト)を減らし、サイトの表示スピードの最適化になる。「サイト・パフォーマンス最適化がGoogleのランキング評価に」もなる時代です。CSSスプライト導入によるサイト・パフォーマンスの最適化で、ユーザ体験の改善ができSEO対策にもなるというのは大きなメリットです。
デメリット
大きなデメリットの一つは、CSSスプライトを導入するために<span>や<i>を使わなくてはならないこと。余計なHTMLを追加するのには、なぜか違和感を覚えます。あと、CSSスプライトについて書かれたブログなどを読んでいると、メンテが大変になると書かれています。実際に運営してみないと分からないですが、しっかりプランして実装すれば意外とメンテは楽になるのでは?と考えています。
スプライト画像の作り方
ググってみたのですが、スプライト画像の作り方に関して特にベストプラクティスのようなものはなさそうです。が、ポイントは以下のような感じでしょうか?
- GIF/PNGで最適化できるアイコン・画像のみを使う
- 写真など、JPEGで最適化しやすい画像はスプライトではなく個別の画像にする
- 同じサイズのアイコンを近くに並べる
- 元画像ファイルのバージョンコントロールをしっかり行う
スプライト画像を表示するためのHTMLとCSS
スプライトを表示させるために必要なHTMLとして、懸念するところは余計なタグを入れる必要があるところです。GoogleやFacebookのような、よりコンパクトなスプライト画像を使用するには、アイコンを表示する際に表示域を指定する必要があります。僕が知る限りでは<span>や<i>を使ってアイコンや矢印を挿入する必要があるようです。Googleはおもに<span>、Facebookは<i>を使っているようです。以下にサンプルを作ってみました。
サンプル
矢印付きのリンクリストで、テキストが2行になっても大丈夫なように、以下のようなHTMLとCSSを組んでみました。
- CSSスプライトを使ったサンプルリンク
- CSSスプライトを使ったサンプルリンクCSSスプライトを使ったサンプルリンクCSSスプライトを使ったサンプルリンクCSSスプライトを使ったサンプルリンクCSSスプライトを使ったサンプルリンク
※ただ、<ul>を使って2行対応にしようとするとどうしても以下のような問題が発生します:
- テキスト部分をブロック指定するため、テキストのない部分がリンクのアクティブ領域になってしまう
- IE8+のみの対応。IETesterのIE6、IE7では表示が崩れてしまいます。Chorme、Firefox、Safari、Operaの最新版では問題なく表示されます。
まだまだ勉強・研究不足でここまでしか対応できてませんが、とりあえず今回はここまでの成果を掲載しておきます。他になにかいい方法があったら、ぜひコメント欄でご教授ください。
スプライト画像
ざっくりですが、アイコンを入れた以下のようなスプライト画像を作成しました:
HTML
テキストが2行になってしまってもアイコンの下に流れこまないように、以下のようなHTMLにしました。アイコンを表示させる部分には<i>を、テキスト部分には<span>を使っています。他にもやり方はあるかと思いますが、思いついたのはこの方法でした。
<ul class="test-list">
<li><a href=""><i class="sprite arr-orange"></i><span>CSSスプライトを使ったサンプルリンク<i class="sprite icon-new"></i></span></a></li>
<li><a href=""><i class="sprite arr-orange"></i><span>CSSスプライトを使ったサンプルリンクCSSスプライトを使ったサンプルリンクCSSスプライトを使ったサンプルリンクCSSスプライトを使ったサンプルリンクCSSスプライトを使ったサンプルリンク</span></a></li>
</ul>
CSS
CSSについても、現状思いつた方法は以下のとおりです。
.test-list {
list-style: none;
overflow: hidden;
}
.sprite {
background: url(https://parashuto.com/rriver/wp/wp-content/uploads/2011/06/css-sprite-sample.png) no-repeat;
}
.test-list span {
display: block;
margin-left: 13px;
}
.arr-orange {
display: block;
float: left;
width: 8px;
height: 9px;
background-position: -8px -19px;
margin: 6px 0 0 0;
}
.icon-new {
display: inline-block;
width: 24px;
height: 9px;
background-position: 0 -28px;
margin: 0 0 0 3px;
}
最後に…
まだまだ未完成で、ちょっと悔しいですが、問題点は今後解決していきたいと思っています。IE6、IE7への対応は、なんとかなりそうな気がするんですが、テキストがない部分がリンクのアクティブ領域になってしまう問題は、いまのところ解決のアイディアが思いつきません。。。Facebookでやってるみたいに、hoverで背景色を変えて対応させるとか…あとはHTMLを増やすとか…邪道でしょうか?
[追記: 2013/1/4]
こちらでこの方法の最終形のデモを紹介しています。
SVGスプライトについての記事
参考までに、こちらもどうぞ
2011年6月19日に公開され、2017年11月23日に更新された記事です。
About the author
「明日のウェブ制作に役立つアイディア」をテーマにこのブログを書いています。アメリカの大学を卒業後、ボストン近郊のウェブ制作会社に勤務。帰国後、東京のウェブ制作会社に勤務した後、ウェブ担当者として日英バイリンガルのサイト運営に携わる。詳しくはこちら。
ウェブ制作・ディレクション、ビデオを含むコンテンツ制作のお手伝い、執筆・翻訳のご依頼など、お気軽にご相談ください。いずれも日本語と英語で対応可能です。まずは、Mastodon @rriver@vivaldi.net 、Twitter @rriver 、またはFacebook までご連絡ください。
[…] サイトの表示速度のことなんかを考えたらアイコンは「CSSスプライト」させる必要とかもありまして。CSSプリプロセッサーを使わない僕には面倒の局地なんですよね。 […]