stylusでbackgroundに指定した画像のサイズ変更に対応する。

スマートフォン向けのcssを書く場合、アイコンなど背景画像として設置することが多いですが、device-pixel-ratioに合わせて高解像度用の画像を用意し、background-sizeでratioの比率に縮小することが多いです。

このとき結構困るのが画像のサイズ、特に横幅が変わってしまうといちいちcssで指定しているbackground-sizeも変えないとならないので、運用を考えると結構めんどくさいです。

うまい方法ないかなぁと考えてたら、stylusに画像サイズを取得するimage-size関数が用意されてたんですね。。。

iconPath = '../images/icon.png'
.icon
  display block
  height 20px
  width @height
  background-image url(iconPath)
  tmp = image-size(iconPath)
  h = tmp[0]/2
  w = tmp[1]/2
  background-size h w

こんな感じで指定してやると、

.icon{
	display: block;
	height: 20px;
	width: 20px;
	background-image: url("../images/icon.png");
	background-size: 500px 50px;
}

半分の画像サイズの値でCSSがコンパイルされてきます(icon.pngは1000px x 100pxの画像)

こうすることで背景に使っている画像のサイズ変更に簡単に対応することができました。

background-positionを%など相対表記していると結局ずれてしまいますが、
僕の場合、アイコンはほとんど::beforeか::after疑似要素を作ってそこに画像を表示させているので、background-positionによるズレを気にしなくてすみました。

最近Sass使ってないから分からないけど、同じような方法がSassにもあると嬉しいなぁ。。

stylusでbackgroundに指定した画像のサイズ変更に対応する。

icon fontとfont-faceを使ったアイコンの表示

CSS-TRICKSに面白いアイコンの表示方法が紹介されていて、触発されたのでサンプルを作ってみた。

Icon Fonts are Awesome | CSS-TRICKS

上記URLのデモはアイコンの様なフォント(というかアイコン)をCSS3のfont-faceを使って表示するというもの。
ここでは空の要素にafter/before疑似要素を使って文字を出してるが、そこはめんどくさいので割愛。

CSS3を使えばwebkit向けであればマスクを使う事ができるので、フォントにグラデーションも掛けてみた。(Androidは現時点でテキストのグラデーションは使えないけど。。)

サンプルページ

fontなのでどれだけ拡大してもアイコンがぼやけることもないし、スマートフォンであれば解像度別に画像を用意する必要もないので非常に便利ですね。
英数字+日本語までいれると用意できる数には問題ないですし、文字自体をCSSの擬似要素で出せばHTML的にも問題ないので個人的にはとても使いたいテクニック。

Androidさえいなければ。。。

デモで使ったフォントは以下のフリーフォントを利用させてもらいました。

Free Icon Font Pack | offset media

icon fontとfont-faceを使ったアイコンの表示

css3のbackgroundでつまずいた。

あまりこんな機会があるとは思えませんが、ちょっとつまずいたのでメモ。

スマートフォンサイトをコーディングする際に、CSSでの背景画像の設定では高解像度画像を使うため、background-sizeを指定してiPhoneであれば2倍の画像を1/2に圧縮して表示させるます。

今回つまずいたのは、background-sizeとグラデーションを一つの要素に適用させる処理です。

CSS3からはbackgroundに複数の画像を設定することができるようになり、
グラデーションはbackground-imageの一つのような扱いで、設置することが出来る。

.ele {
	background-image: url(img/logosample.png),
			-webkit-linear-gradient(top, #f6f7f7 0%, #4d516a 100%);
	background-repeat: no-repeat , no-repeat;
	background-position: 0 0, 0 0;
}

スマートフォン対応をする場合、画像の部分はbackground-sizeで縮小して高解像度画像を表示させるため、画像を指定した方にだけsize指定する。

.ele {
	background-image: url(img/logosample.png),
			-webkit-linear-gradient(top, #f6f7f7 0%, #4d516a 100%);
	background-repeat: no-repeat , no-repeat;
	background-position: 0 0, 0 0;
	background-size: 0 100px , auto;
}

もしbackground-sizeを一つだけしか指定しないと、グラデーションもサイズ変更されてしまうので注意が必要。

ここまでは問題なかったが、これをショートハンドで指定するとどうもうまく行かない。

W3CのCSS3 backgroundショートハンドプロパティのの説明はこんな感じ。

<bg-layer> = <bg-image> || <bg-position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <box>{1,2} 
 
<final-bg-layer> = <bg-image> || <bg-position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <box>{1,2} || <'background-color'>

W3C The ‘background’ shorthand property

この記述に習って書いてみたけど、どうもうまくいかない。

[class^="sample"]{
	box-sizing: border-box;
	height: 200px;
	width: 300px;
	margin: 10px;
	border:  solid 1px #ccc;
	padding:  10px;
}
.sample1 { // background-size指定なし
	background: url(img/logosample.png) no-repeat 0 0,
			-webkit-linear-gradient(top, #f6f7f7 0%, #4d516a 100%);
}
.sample2 { // background-sizeをショートハンド外に一個だけ指定
	background: url(img/logosample.png)  0 0 no-repeat ,
			-webkit-linear-gradient(top, #f6f7f7 0%, #4d516a 100%);
	background-size: 100px 100px; 
}
.sample3 { // background-sizeをショートハンド外に両方指定
	background: url(img/logosample.png)  0 0 no-repeat ,
			-webkit-linear-gradient(top, #f6f7f7 0%, #4d516a 100%);
	background-size: 100px 100px , auto auto;
}
.sample4 { // background-sizeをショートハンドで両方指定
	background: url(img/logosample.png) 0 0 / 100px 100px  no-repeat;
	/*-webkit-linear-gradient(top, #f6f7f7 0%, #4d516a 100%) 0 0 / auto auto no-repeat; */
}

背景画像とグラデーションのサンプル

複数指定をする場合、backgroundショートハンドは読みにくいのであまり使うことはなかったから気付かなかったけど、どうやら動作しないっぽい。それとも書き方が間違ってるだけなのか。。。?一通りの現時点での最新ブラウザで確認したけどダメ。

これって未対応なんでしょうか??
まぁ個人的にはプロパティを分けて書く方が読みやすくもあるからショートハンドは使わないけど、ショートハンドで書く場合はbackground-sizeは一緒に書かない方がいいっぽいですね。。

css3のbackgroundでつまずいた。