一から勉強させてください( ̄ω ̄;)

最下級エンジニアが日々の学びをアウトプットしていくだけのブログです。

CompassでCSS Sprite生成(手動生成、Retina対応)

今回は、前回やったCompassでCSS Sprite生成〜導入、自動生成〜の続きとして、CSS Spriteの手動生成とRetina対応について書きたいと思います。


ちなみに前回と今回のサンプルをまとめてこちらに公開しておりますので、もしよかったら見てやってください!!

https://github.com/danimal141/create_css_sprite


それではまずCSS Spriteの手動生成についてです。

前回は
 

@import "compass";

$sprite_images-sprite-dimensions:true;
@import "sprite_images/*.png";
@include all-sprite_images-sprites;

という記述だけであっという間にスプライト用のCSSができちゃいましたが、これ以外にも同様のスタイルを生成する方法があるみたいなので試してみました。


これ。

@import "compass";


//スプライト画像の生成、戻り値としてbackgroundのurlが返ってくる
$sprite_sample_img:sprite-map("sprite_images/*.png");

$base-class: sprite-map-name($sprite_sample_img);


.#{$base-class}{
	display: block;
	overflow: hidden;
	text-indent: 100%;
	white-space: nowrap;
	background:$sprite_sample_img no-repeat;
	@include background-size(image-width(sprite-path($sprite_sample_img)) image-height(sprite-path($sprite_sample_img)));
}

//sprite-map, sprite-positionは関数、sprite-dimensionはmixinなので、includeする必要あり

@each $sprites in sprite-names($sprite_sample_img){
	.#{$sprites}{
		@include sprite-dimensions($sprite_sample_img, $sprites);
		background-position:sprite-position($sprite_sample_img, $sprites);
	}
}


これで前回作成したCSSと同様のCSSが作成されました。
(今回はせっかくなので、文字飛ばし用のスタイルを追記しています。)

流れとしては、

まずsprite-map()の引数に「スプライトのパーツ画像が入っているディレクトリ/*.png」を指定してやると、それらを結合したスプライト画像を生成してくれます。さらに戻り値として、backgroundのURLが返されます。
今回は$sprite_sample_imgという変数を用意して、そいつに格納しました。
                         ↓

次にsprite-map-name()に先ほど取得したbackgroundのURLを指定してやればスプライトのパーツ画像を入れてあるディレクトリ名を返してくれるみたいです。
これを$base-classに格納して、後でクラス名として使う事にします。

                         ↓
クラス名を.#{$base-class}として(これはRubyの書き方ですね、たぶん)そこにベースとなるスプライトの命令を書いていきます。

background-sizeはCompassでもともと用意されているimage-width(), image-height()を使用。
image-width、image-heightに先ほどのURLを指定してスプライト画像のwidthとheightを取得して、適用します。

                         ↓
 
あとはsprite-names()で全パーツ画像を取得して、@eachで個々のパーツクラスにそれぞれのpositionとwidth,heightを指定してやればOK。

注意点としては
sprite-positionは関数であるのに対して、sprite-dimensionはmixinなので、includeする必要あるというところです。


こんな感じでより細かい指定をしながらスプライトのスタイルを作る事ができました。


次にRetinaディスプレイ対応のスプライトについて考えます!!

これは以前、Retinaについて考察した際にもちょっと書きましたが、Retinaで画像を使用する場合は2倍の解像度の画像を用意して、それをCSSで半分のサイズで指定する必要があります。

この原理はスプライト画像に関しても同様で、widthやheight、background-positionすべてを半分の値で指定してやる必要があります。


そこで今回はこちらの方のソース↓

https://gist.github.com/haribote/4072251

を参考にさせていただきながら、

Retina用のスプライト画像、スタイルを生成する_mixin.scssを用意してみました!!

//_mixin.scss

@mixin retina-sprites_style($map, $dimensions: false){
	
	$base_sprite_class: sprite-map-name($map);

	.#{$base_sprite_class}{
		display:block;
		overflow:hidden;
		text-indent:100%;
		white-space:nowrap;
		background: $map no-repeat;
		@include background-size(ceil(image-width(sprite-path($map)) / 2) ceil(image-height(sprite-path($map)) / 2));
	}

	@each $sprite in sprite-names($map){

		.#{$sprite}{

		//個々の画像サイズが欲しい場合ははじめに$dimensions:trueとする
		  @if $dimensions{
		    width: ceil(image-width(sprite-file($map, $sprite)) / 2);
		    height: ceil(image-height(sprite-file($map, $sprite)) / 2);
		  }

		  $position: sprite-position($map, $sprite);
		  background-position: ceil(nth($position, 1) / 2) ceil(nth($position, 2) / 2);
		}
	}
}


先ほど書いたものと違う点は


・width,height,positionをそれぞれ2で割った値を適用しているところ
・sprite-dimensionsではなく、sprite-file($map, $sprite)で各々の画像サイズを取得するようにしているところ


ぐらいです。


結構スプライト関連の命令って多いんですね。。


んであとはこのmixinを呼び出す方の.scssをつくってやれば完成。

mixin使う.scssのほう↓

@import "compass";
@import "mixin";

$sprite_img : sprite-map("sprite_images/*.png");
@include retina-sprites_style($sprite_img, $dimensions : true);


これでRetina用のスプライトのスタイルを作成する事ができました!!


ちゃんともとの画像解像度の半分のサイズでスタイルが適用されていました!!これはめっちゃ便利ですね!!


ちなみに最後に復習として、sprite-なんたらみたいな命令を一通りdebugで見てみました。
どんな値が返ってくるのかメモとして書いときます。

@debug sprite-map-name($map);   →DEBUG: sprite_images

@debug sprite-path($map);  →DEBUG: sprite_images-s036833e88e.png

@debug sprite-url($map);  →DEBUG: url('../images/sprite_images-s036833e88e.png')

@debug image-width(sprite-path($map));  →DEBUG: 50px

@debug sprite-names($map);  →DEBUG: sprite_img1, sprite_img2, sprite_img3, sprite_img4, sprite_img5

@debug sprite-file($map, sprite_img1);  →DEBUG: sprite_images/sprite_img1.pngの絶対パス

@debug sprite-position($map , sprite_img2);  →DEBUG: 0 -96px

@debug nth(sprite-position($map , sprite_img2),1);  →DEBUG: 0


今までスプライト画像って、Photoshopとかで細かく画像の位置とか調整したりしてめちゃめちゃダルかったんですが、Compassさえあれば、Retinaだろうがなんだろうがすぐに生成、編集できますね!!

まああとダルいのはパーツ画像の切り出しぐらいでしょうかw まあそれぐらいなら全然苦じゃないです!!


もっと実務でも使っていきたいなー

機会ないかなー

小さなことからコツコツと。