話題の記事

コーダー必見、SCSS・Compassで開発効率アップ|便利なCSS Sprite実装編

2012.11.29

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

今回から「すぐに使えるSCSS入門シリーズ」からタイトルを変えてSCSS・Compassを使ったコーダー向け開発効率アップテクニックを紹介していきます(シリーズは続きます)。

今回作成したサンプル

このサンプルはgithubで配布しています。ダウンロードしてソースなどご確認ください。
動作するHTMLサンプルはこちらです。

CSS Spriteって?

CSS Spriteについてお復習いです。
簡単に言うと画像をくっつけてCSSのbackgroud-positionで表示を制御するテクニックです。

CSS Spriteのメリット

  1. 画像をくっつけることによってHTTPリクエスト数の削減
  2. マウスオーバーなどで表示を切り替えるがスムーズ(個別に画像を読み込んでいる場合、切り替わったときに読み込みが発生します)
  3. CSSのみでボタンなどのアフォーダンスを切り替えることができる

CSS Spriteのデメリット

  1. 画像をまとめて作るのが手間
  2. 画像に変更があった場合、座標の変更が手間
  3. 画像をまとめる際に汎用性を考えどの座標に配置するか頭を使う
  4. デザインする際に書き出しようのファイルを作る必要がある
  5. alt属性は使えずテキストを置くことはできるが、テキストを見えなようにするテクニック(画像置換)は要注意

CSS Spriteは価値のあるテクニックですが上記のような手間のかかるものでもあります。
そこでSCSS・Compassを使うことでほとんどのデメリットを解消することができます。

Compassで解消できるCSS Spriteのデメリット

1, 画像をまとめて作るのが手間

Compassすごい!特定のフォルダの画像をすべてくっつけて1枚の画像にしてくれます。

2, 画像に変更があった場合、座標の変更が手間

Compassを使うことでくっつける前の画像名を指定するとその画像の座標を返してくれます。画像を変えてもCSSの変更は必要ありません。

3, 画像をまとめる際に汎用性を考えどの座標に配置するか頭を使う

Compassには4つの配置ルール(後述)があり、ほとんどの場合これで十分です。頭を悩ませる時間が減ります。

Compassで解決できないデメリット

4, デザインする際に書き出しようのファイルを作る必要がある

特にPhotoshopでデザインをする方にとっては大きな課題です。ただ、これはフリーのプラグイン「Cut&Slice me」を利用することで解決できます。
Cut&Slice meについては別の記事で紹介します。

5, alt属性は使えずテキストを置くことはできるが、
テキストを見えなようにするテクニック(画像置換)は要注意

text-indent:-9999px;などでテキストを見えなくする処理は悪用することもできるテクニックなので利用については要注意です。
一般的な利用では問題にはならないと思いますが検索エンジンからスパムと見られることも可能性としてあることを理解した上で利用しましょう。

要注意なデメリットは5の画像置換ぐらいというわけです。
使うしかないですよね。ではCompassのCSS Spriteヘルパーを紹介していきたいと思います。

CompassのCSS Spriteヘルパーについて

CSS Sprite Helpers for Compass

Compassにはヘルパーを使わないSpriteの指定と関数でできたヘルパーを使う方法があります。
ヘルパーの方が簡単なので今回はヘルパーの紹介をしたいと思います。サンプルのソースコードと合わせて読んでみてください。

Spriteの手順

spriteの指定はこんな手順になります。

  1. 画像を書き出し1つのフォルダにまとめる
  2. configを設定する
  3. CSSでspriteの定義を行う(function: sprite-map())
  4. backgroundにマージされた画像を設定する(定義した変数を指定)
  5. 任意の要素にbackground-positionで座標指定を行う(sprite-position())

1, 画像を1つのフォルダにまとめる

まずはくっつけたい画像をまとめましょう。

2, configの設定

アップロードする環境に合わせてhttp_pathやhttp_images_dirなどを設定します。
このサンプルではgithubのpagesにアップロードするのでこのような指定にしました。

http_path = 'http://nonakaryuichi.github.com/scss_sprite_sample/'
http_images_dir = 'images/'

3, Spriteの定義

ヘルパーを使いSpriteの定義とくっつけた画像を作成します。
第一引数にくっつける画像を指定します。*.pngを指定することで特定の拡張子の画像をくっつけることができます。

$btns: sprite-map("btn/*.png", $spacing: 20px, $layout: horizontal);

$spacing

画像の間の間隔を指定できます。

$layout

くっつける際の画像の配置を指定します。vertical, horizontal, diagonal, smartの4つから選ぶことができます。

  • vertical(縦方向に配置)
  • horizontal(横方向に配置)
  • diagonal(上下左右に余白を設け斜めに配置)
  • smart(無駄な余白を極力減らすよう調整して配置)

4, backgroundにくっつけた画像を設定

3でくっつけた画像を背景に指定します。$btnsにはくっつけた画像の指定が入っています。
テキストを見えなくしたいので、「overflow:hidden;」「text-indent:100%;」 「white-space:nowrap;」を指定します。

a
{
        //layout
        display:       block;
        overflow:     hidden;
        width:          81px;
        height:         81px;

        //typo
        text-indent:    100%;
        white-space:  nowrap;

        //background
        background : $btns no-repeat;
}

5, background-positionで配置を調整する

調整するといっても名前を指定するだけです。簡単ですね。
sprite-position(定義された変数, 画像の名前)は定義された変数と、元の画像名の拡張子を抜いたものを指定します。

a
{
        background-position:
                sprite-position( $btns, btn_home_normal );
}

a:hover
{
        background-position:
                sprite-position( $btns, btn_home_hover );
}

a:active
{
        background-position:
                sprite-position( $btns, btn_home_pressed );
}
a:target
{
        background-position:
                sprite-position( $btns, btn_home_selected );
}

決まったサイズのSpriteはpositionを調整するだけなのでとても簡単です。
ちょっと難しくなるのが「サイズの違う画像をくっつけた時、画像のサイズはどう取得するのか?」についてですね。
もちろんこれも解決方法が用意されています。

画像のサイズを取得する

Compassに画像のサイズを取得するためのヘルパーが用意されています。
それがimage-width(対象の画像パス)とimage-height(対象の画像パス)です。使い方は簡単。

image-width()とimage-height()をwidthとheightに直接指定します。第一引数には対象となる元画像のパスを拡張子付きで指定します。

a
{
        width:  image-width('links/link_copyright.png');
        height: image-height('links/link_copyright.png');

        background-position:
                        sprite-position( $links, link_copyright );
}

演算も行えるので簡単に調整できますね。

a
{
        width:  image-width('links/link_copyright.png') + 20px;
        height: image-height('links/link_copyright.png') + 20px;

        background-position:
                        sprite-position( $links, link_copyright );
}

サンプル

実際に設定してみたサンプルはこちら。↓インラインフレームです。

まとめ

デメリットも多く解消でき、便利なCompassを使ったCSS Spriteでした。SCSSを使うことでRetinaディスプレイ向けの対応もそれほど難しいものではなくなりますね。
次回はSCSS、Compassを使ったRetinaディスプレイ対応を紹介してみたいと思います。

個々の画像はCut&Slice meを使って書き出しを行っています。
ボタンのアイコンはiconSweets2を使わせていただきました。