PhotoMani

透過pngでbox-reflect

box-reflect

CSS3のbox-reflectプロパティを用いると画像の鏡面反射エフェクトを簡単に掛けることができます.ここでは透過pngを用いたbox-reflectの適用方法について解説します.

box-reflectプロパティ

PhotoManiではbox-reflectプロパティを用いた鏡面反射エフェクトを随所で使用しており,次のようなコードで実装できます.

[css]
img {
-webkit-box-reflect: below 5px -webkit-gradient(
linear,
left bottom,
left top,
from(rgba(255,255,255,0.5)),
color-stop(0.2,transparent),
to(transparent)
);
}
[/css]

ここで”-webkit-“が付いていることからわかるように,box-reflectは今のところwebkit系ブラウザのみが対応しているプロパティです(2013/3現在).ベンダープレフィックスを省略すると,box-reflectの値は次のように指定できます.

[css]
box-reflect: 反射方向 開始位置 マスク;
[/css]

反射方向は”above”, “right”, “left”, “below”から選択し,開始位置は反射画像と元画像の間隔を指定します.先のPhotoManiの例に当てはめると,反射方向は下向き(below),反射画像の開始位置は下方向に5pxずれた位置となります.
マスクを省略するともと画像をそのまま反転させた画像が表示されますが,例えばここにグラデーションを指定すると鏡面反射のような効果を付けることが出来ます.(先の例では”-webkit-gradient”を用いています.)

box-reflect

box-reflectを用いた鏡面反射エフェクト

マスクに透過png

本来であればwebkit系ブラウザ(safari, mobile safari, chrome, Androidブラウザ)に対しては前述のコードで鏡面反射が得られるはずです…が,一つ問題があります.実はAndroidブラウザでは”-webkit-gradient”プロパティが無視されてしまうのです.その結果マスクを指定しなかったことになり,単に反転した画像が表示されるだけとなってしまいます.これではとても鏡面反射とはいえません.
このAndroidのバグ(?)を回避する方法として,マスクに画像を使うというやり方があります.マスク画像は透過pngとして作成し,先の例で言えば「始点が0.5透過,高さ20%位置で完全透過」となるようなグラデーション画像になります.

透過画像

マスク画像

ここで,マスク画像サイズは元画像の幅と高さに合わせて拡縮されるので適当で良いですが,高さ(反射方向)に大きく拡大されるとマスクの分解能が粗くなるため,元画像が大きなものに適用する場合はマスクもある程度大きくしておいた方が良いかもしれません.
マスク画像が出来れば,あとは次のようにbox-reflectにマスク画像のurlを指定するだけです.

[css]
img {
-webkit-box-reflect: below 5px url(./reflect.png);
}
[/css]

これでAndroidでも鏡面反射効果が得られるようになります.今はwebkit系でしか使えませんが,手軽にwebサイトをリッチに出来るおすすめのテクニックです.