Sass/Compassを使ってCSSスプライトに挑戦してみました。

CSSスプライトを作成する機会があったため、最近よく耳にするSassとCompassを使ってみました。CSSスプライトとは、複数の画像を1枚の画像としてまとめ、CSSで表示範囲を指定することにより表示する手法です。画像のリクエスト数を削減することができるため、高速化の手法の1つとして利用されています。

Sass/Compassについて

 Sassとは、CSSの拡張メタ言語です。独自の文法で記述したファイルをコンパイルして、CSSを生成します。独自の文法といっても、CSSをそのまま書くこともできますし、CSSをベースに拡張されているので学習コストは低いです。変数や演算、ミックスインと呼ばれる関数のような仕組みや継承、条件式などの文法があり、CSSの冗長性や保守性、生産性の悪さを解消することができます。公式サイトは英語ですが、enja-ossというプロジェクトでリファレンスの日本語訳が進められているようです。
 次にCompassとは、sassのフレームワークで、様々なミックスインやスタイルが用意されています。CSSスプライトをはじめ、ベンダープレフィックスを自動で追加してくれたり、sassファイルの変更を監視して自動でコンパイルしたりと便利な機能が満載です。今回は、このCompassのCSSスプライトの機能を使ってみます。Sass/Compassのインストール、設定ファイルの記述については割愛します。

CompassでCSSスプライト

 CSSスプライトを生成するためには、まずSass管理下の画像ディレクトリ内に任意のディレクトリを作成し、スプライトの元となる画像を用意します。今回は以下のような構成で画像を用意しました。

続いて、.scssファイルを用意します。最低限書かなければいけないのは、以下の4行です。この4行で、指定したフォルダ内の画像をCSSスプライト画像にまとめ、表示用クラスを生成することができます。

 @charset “utf-8”;
 @import “compass”;
 
 // スプライト画像を生成
 @import “icons/*.png”;
 // 各画像の表示用クラスを生成
 @include all-icons-sprites();

このsassファイルをコンパイルすると、3つの画像を縦方向1列にまとめた画像(icons-s845e2a1d5b.png)と、以下のCSSが生成されます。クラス名は、「ディレクトリ名-ファイル名」になります。

icons-s845e2a1d5b.png

 .icons-sprite, .icons-cat, .icons-lion, .icons-panda {
   background: url(‘/images/icons-s845e2a1d5b.png’) no-repeat;
 }
 
 .icons-cat {
   background-position: 0 -100px;
 }
 
 .icons-lion {
   background-position: 0 0;
 }
 
 .icons-panda {
   background-position: 0 -200px;
 }

クラス名は保持したままbackground-positionの値を変更したい

 ただ、Retinaディスプレイ対応などbackground-positionの値を元の画像のサイズではなく別の値に変更したい場合、上記だけでは対応できません。そこで、mixinを作成します。クラス名の「ディレクトリ名-ファイル名」というルールは保持したいので、スプライトの元画像のファイル名のクラス名のCSSを出力する処理を書いてみます。sprite-names($map)でスプライトの個々の名前を取得することができるので、これを利用します。

    @charset “utf-8”;
    @import “compass”;
 
    @import “icons/*.png”;
    $spr-imgs: sprite-map(“icons/*.png”);
 
    // 2倍に拡大して表示する用にbackground-positionを指定するmixin
    // 今回は低解像度で表示したいため2倍にしていますが、retina対応の場合1/2になります。
    // 「compass sprite retina」で検索すると色々な方がmixinを書かれています。
    @mixin low-reso-sprites($name){
 
      // heightとwidthも出力してみます
      height: image-height(sprite-file($spr-imgs, $name))*2;
      width: image-width(sprite-file($spr-imgs, $name))*2;
  
     // background-positionを計算して変数に保持します
      $ypos: round(nth(sprite-position($spr-imgs, $name), 2) *2);
      background-position: 0 $ypos;
    }
 
    // 画像の数分のクラスを出力します
    @each $sprite-name in sprite-names($spr-imgs) {
     .#{$sprite-name} {
      @include low-reso-sprites($sprite-name);
     }
    }

この.scssファイルをコンパイルすると、以下のようなcssが作成されます。

 .icons-sprite {
   background: url(‘/sass/images/icons-s845e2a1d5b.png’) no-repeat;
 }
 
 .icons-cat {
   height: 200px;
   width: 200px;
   background-position: 0 -200px;
 }
 
 .icons-lion {
   height: 200px;
   width: 200px;
   background-position: 0 0;
 }
 
 .icons-panda {
   height: 200px;
   width: 200px;
   background-position: 0 -400px;
 }

background-positionの値を変更することが出来ました!上記のクラスを実際に適用する要素では、background-sizeで背景画像のサイズを2倍にして使用しました。
 

容量比較

 CSSスプライト化すると、どれだけ容量が削減できるのか比較してみます。以下は15個のオリジナル画像(PNG)をCSSスプライト化した結果です。画像とCSSを合わせても、約3分の1に容量を削減することができました。

形式オリジナル画像スプライト画像CSS容量備考
CSSスプライト(PNG)24.3KB5.04KB1.55KB容量は0.27倍

Related Post

position:fixedを実現するiScrollを使う際に覚えておきたいメソッドたちposition:fixedを実現するiScrollを使う際に覚えておきたいメソッドたち

ヘッダーやフッター等の要素を固定表示するのに利用されるposition:fixed。このposition:fixedがサポートされていない環境で、固定表示を実現する際によく使われるライブラリにiScrollがあります。要素を固定するというよりは、特定要素の範囲をスクロール可能にする、overflow:autoのようなイメージです。 複雑なレイアウトになると、iScrollでスクロールさせている要素の高さが動的に変化したり、スクロール領域が入れ子だったり・・・ユーザ操作に応じて追加の処理を行う必要があります。難しそうなレイアウトは設計の際に回避したいところですが、そういう実装が必要な場合に使えるiScrollのメソッドをまとめてみました。 iScrollの使い方 iScrollの使い方ですが、HTML要素に任意のIDを付け、JSで初期化を行います。下記の例ではid=”scroller”の要素がスクロール可能になります。例でリスト要素になっている部分は何でもかまいませんが、2つのwrapper(例ではIDがwrapperとscrollerのdiv要素)は必要です。また、一番外側の要素には高さを指定しておく必要があります。 ◆HTML <div id=”wrapper”><div id=”scroller”><ul><li></li>……</ul></div></div>

IllustratorからSVGを書き出して、SVGアニメーションを追加するIllustratorからSVGを書き出して、SVGアニメーションを追加する

iOS5のアップデートに伴い、Mobile SafariがインラインSVGに対応しました。そこで、このiOS5のMobileSafari向けに、キャラクターのイラストをIllustratorで書き出し、SMILアニメーションに挑戦してみました。   SVGをアニメーションさせる際の選択肢 SVGで書き出したグラフィックをアニメーションさせる場合、DOM操作、SMILアニメーションなどいくつかの方法があります。 ・SMILアニメーション・CSS3アニメーション・JavaScriptでの属性値変更・Canvasアニメーション SVGの仕様は非常に大きく、アニメーション機能としてSMIL Animationをサポートしています。SMILとは、Synchronized Multimedia

Gruntで快適な環境を整備したい!【タスク記述編】Gruntで快適な環境を整備したい!【タスク記述編】

『Gruntで快適な環境を整備したい!【インストール編】』に引き続き、タスクの自動化ツールであるGruntを使ってみます。今回はタスク記述編ということで、様々なタスクを書いてみます 今回したいこと 今回は以下のタスクを書いてみたいと思います。タスクはGruntfile.jsに書きます。ベースとなるコードは前回の記事『Gruntで快適な環境を整備したい!【インストール編】』の「Gruntfile.jsを作成する」をご覧ください。 タスクの中身は基本的に、処理対象となるファイルやフォルダのパスと処理後のパスで構成されています。ファイルパスの書き方には「コンパクト形式」「ファイルオブジェクト形式」「ファイル配列形式」があります。Gruntのドキュメントを日本語化してくださっているサイトがありますので、こちらを参考にしてください。プラグインによってはサポートしていない形式があるようですので、どのプラグインがどの形式をサポートしているかは各プラグインのドキュメントを参照してください。 ■ファイル、フォルダの複製 ファイル、フォルダの複製にはgrunt-contrib-copyを使います。納品用に必要なファイルをすべてbuildフォルダ下にコピーしてみます。   copy: {    dist: