Compass で画像サイズを取得して背景画像に利用するミックスインを書いてみた
テキストを画像に置き換えたい場合があります。例えば、見出しの h1 ~ h6
タグのテキストを画像にする場合です。
実装としては、見出しタグの中身に img
タグを含める方法と、CSS で処理する方法があります。
前者は、簡単な方法ですが、保守を考えた場合、疑問です。複数ページにその都度 img
タグが置かれているのをちまちま修正するより、CSS で一括で修正できる方が良い気がします。
※ ただ、img
タグをそのまま含める場合には、レスポンシブに画像を表示(縦横の比率を保ったまま拡大・縮小)できる大きなメリットが存在します。これは、CSS では表現できないため、今の技術ではそうせざるを得ないことがあります。
この記事では、CSS でテキストを画像に置換する際に、便利なミックスインを作ってみます。Sass & Compass 環境が必要です(導入方法)。
ミックスイン(Mixin)とは
ミックスインは、ひとまとまりのスタイルを再利用するための便利な Sass の仕組みです。簡単にいえば、関数のようなものです。@mixin 名前(変数)
のように宣言します。そして使う場合は、@include 名前(変数)
とすれば OK です。
例えば、border-radius
にベンダープレフィックスを付けるようなミックスインを考えてみます。次のように書いてみました。
/* .scss */
@mixin radius($px) {
-moz-border-radius: $px;
-webkit-border-radius: $px;
border-radius: $px;
}
code {
@include radius(10px);
}
これは、次のように変換されます。指定したサイズで角丸が表現できています。
/* .css */
code {
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
}
Compass で画像のサイズを取得するには
Compass を導入しているならば、config.rb で監視している画像フォルダにある画像の縦横を取得できます。公式サイトを参考に横幅を取得する image-width($image)
と縦幅を取得する image-height($image)
を使えば良さそうです。
また、画像のパスを取得するには、image-url($path, $only-path, $cache-buster)
を使うようです。パラメータが複数指定できますが、それぞれ画像名、パスだけか(ブール型)、キャッシュを意識するか(ブール型)、となっています。
テキストを画像に置換するミックスイン(レティナ対応)
レティナ対応を意識したミックスインを作成しました。名前と解像度からテキストを画像に置換する CSS が出力されます。解像度は入力を省いた場合、1 が標準で設定されます。
/* .scss */
@mixin bg($name, $dpi: 1) {
$width: image-width($name) / $dpi;
$height: image-height($name) / $dpi;
display: block;
width: $width;
height: $height;
background: image-url($name, false, false) no-repeat;
background-size: $width $height;
text-indent: 100%;
white-space: nowrap;
overflow: hidden;
}
h1 {
@include bg("about.png", 2); // about.png 画像のレティナ対応お願いします!
}
これをコンパイルすれば、以下のように出力されます。about.png は元々が 48x48 の画像なのでちゃんと動作していることが確認できます。
/* .css */
h1 {
display: block;
width: 24px;
height: 24px;
background: url("../images/about.png") no-repeat;
background-size: 24px 24px;
text-indent: 100%;
white-space: nowrap;
overflow: hidden;
}
このようにミックスインを使えば、だらだらと記述しなければならなかったところを 1 行で済ませられ、可読性が上がっています。もう一度、画像は違うけれど同じようなことをしたい場合、新しく書くのは 1 行だけで OK です。