CSSスプライト。

〜細かい画像を多数使う場合〜

CSSの小技として、細かい画像を多数使う場合に役に立つCSSスプライトについて、制作者なりに平易に解説してみました。

CSSスプライトとは。

CSSスプライトとは、細かい複数の画像をCSSで表示させる技術です。

具体的には、複数ある細かい画像を一枚のGIF画像などにまとめ、それの一部分だけを表示させると言うものです。

CSSスプライトの効用。

特に複数あるアイコンを文書内で多用する場合には、サーヴァへの負荷を軽減させる効果が期待出来ます。

例えば、いわゆるガラケー(スマートフォン以前の携帯電話)向けのコンテンツをPC向けに配信したい場合、絵文字の問題があります。

携帯電話用の絵文字は、多くの場合該当する文字を表すGIF画像などを<img>要素で埋め込みますが、その方法だと絵文字が多いコンテンツではサーヴァへの画像リクエストが多数発生してしまい、サーヴァへの負荷に繋がってしまいます。

CSSスプライトでは、予め使用したい絵文字を一枚にまとめたものを一回だけ読み込んで、それを使い廻していくため、絵文字の使用数が多ければ多いほどサーヴァへの負荷を減らせる効果が期待出来ます。

CSSスプライトを実現するには。

CSSスプライトを実現するには、以下のようにします。

アイコン類を纏めた画像の用意。

先ず、サイト内で多用されるであろうアイコン類を一枚に纏めた画像を用意します。

この画像はGIF画像にする事になるでしょうが、二百五十六色以上の場合にはトゥルーカラーのPNG画像にしたくなるかも知れません。

  • 但し、トゥルーカラーのPNG画像は非常に重くなります。かと言ってJPEG画像だと画像の鮮度が落ちるので、なるべく二百五十六色以内に抑えてGIF画像かインデックスカラーのPNG画像にする事をおすすめします。
  • どうしてもフルカラーの画像にしたい場合は、二百五十六色以内にまとまる画像とフルカラーの画像をそれぞれGIF画像かインデックスカラーのPNG画像とJPEG画像かトゥルーカラーのPNG画像と言うように二つの画像に分けた方が良いでしょう。

実際のCSSでの考え方。

CSSスプライトは、見た目としては、用意した画像の一部を切り取って希望する箇所に貼り付けて行くと言うものに見えます

ですが、実際にはCSSには画像の一部を切り取って貼り付けると言う概念はありません

  • あくまでも概念としては存在しないと言う事です。

そこで、そのような効果が結果として出せる代わりの方法を考える事となります。

具体的な考え方。

CSSスプライトの概念図
CSSスプライトの概念図(GIF画像)

具体的には、アイコンの大きさに合わせた表示領域を取り、そこに背景画像として用意した画像を貼り付けていきます。

このとき、背景画像の表示位置にマイナスの値を与える事で、画像の表示位置をずらせることになります。

表示領域ですが、これはインラインブロックの形式にします。

  • 文章中に埋め込むので、インラインとなりますが、インライン方式では幅と高さを定める事が出来ません。
  • 尚、インターネットエクスプローラ 7.0までではインラインブロックはサポートされておりませんが、バグを用いる事で同様の表示が可能になります。

CSSスプライトの実例。

CSSスプライトを用いた実際の例をご紹介しましょう。

今、iモード向けコンテンツをPC向けに配信するため、絵文字をCSSスプライトで実現する事とします。

iモード用絵文字を纏めた画像として、以下のGIF画像が用意されているものとします。

  • ※この箇所には"iモード用絵文字を纏めたGIF画像"として、幅335ピクセルズ、高さ330ピクセルズのGIF画像が入ります

そして、HTML文書内にある以下の文章の、

  • (はぁと)。の箇所に、ハートマークの絵文字画像を
  • 末尾の感嘆符の代わりに、感嘆符二つの絵文字画像を

それぞれ埋め込む事にします。

<p>
    堀北真希ちゃんって、可愛いよな(はぁと)。
    堀北真希ちゃんは俺の嫁!
    </p>

HTML側の細工。

先ず、CSSを使う以上、CSSがセレクタで認識出来るようにしなければなりません。

  • スタイルのためにHTMLをいじるのは抵抗があるかも知れませんが…。

絵文字を埋め込みたい箇所に、以下のように<span>要素を埋め込みます。

  • マークアップは非視覚系環境で画像がない場合に適切であろうテキストに行います。
<p>
    堀北真希ちゃんって、可愛いよな<span class="emoji docomo80">(はぁと)。</span>
    堀北真希ちゃんは俺の嫁<span class="emoji docomo160">!</span>
    </p>

ここで、各所にわざわざクラス名を二つ与えたのは、以下の考えに基づきます。

  1. emoji クラス名は、絵文字のための表示領域を意味します。
  2. docomo80 クラス名及び docomo160 クラス名は、ドコモ式絵文字のそれぞれ絵文字番号80(ハートマーク)及び絵文字番号160(二重感嘆符)を埋め込む領域である事を意味します。

前者は結構記述が多いので、各絵文字ごとに記述するのは大変ですから、単一のクラス名で扱う事とした訳です。

  • まぁ、この後読み進めば、お分かり頂けるかと思いますが…。

スタイルシートの作成。

続いて、以下のようにスタイルを定めます。

.emoji {
    display: inline-block;
    width: 16px;
    height: 16px;
    background: transparent url('CSSSprite_Image.GIF') -1000px -1000px no-repeat;
    vertical-align: middle;
    text-indent: -9000px;
    }

.docomo80 {
    background-position: -319px -77px;
    }

.docomo160 {
    background-position: -128px -213px;
    }

スタイルシートの内容は以下のようになります。

emoji クラスへの指定

docomo80 クラスへの指定

docomo160 クラスへの指定

docomo80 クラス及びdocomo160 クラスについては、併せて指定しているemoji クラスのスタイルに依って、適切な表示形態と表示すべき画像が指定されております。

  • 言い換えれば、同じ記述を何度も繰返すのを避けるため、わざわざ emoji クラスを併せて指定した訳です。

ただ、画像の表示位置が不適切ですので、それを上書きするため、background-positionで画像の左端と上端の、表示領域の左端と上端からのそれぞれの相対位置を調整します。

適切な値は、画像内にある表示させたいアイコンの左端及び上端の、画像全体の左端及び上端からの相対座標を負にしたものとなります。

サンプル。

現行のウェブブラウザ(ファイヤーフォックスなど)で、且つ画像を読み込んで表示する設定でご覧になると、以下のサンプル内の二箇所に絵文字が表示されている筈です。

堀北真希ちゃんって、可愛いよな(はぁと)。 堀北真希ちゃんは俺の嫁

CSSスプライトに於ける注釈。

インターネットエクスプローラ 7.0までについて。

インターネットエクスプローラ 7.0まででは、display: inline-block プロパティは実装されておりませんが、(制作者の環境では)結果的に問題なく処理されているようです。

どうも、インターネットエクスプローラ 7.0まででは、インライン要素形式の場合であっても、間違ってwidthプロパティやheightプロパティを認識してしまうようです。

  • 認識出来ない displayプロパティがある場合、inline値と認識しているようです。一応、この挙動は正しいのですが、このタイプでは概念すらないwidthプロパティやheightプロパティが認識されるのが問題です。

CSSスプライトに関するまとめ。

一枚に纏めた画像をCSSを用いて使い廻す事で、サーヴァへの負荷を軽減させ、且つ閲覧者側もよりスムーズな閲覧が期待出来ます。

特に上記のように、絵文字を多用した文書には特に有用でしょう。