JavaScriptも使わず元画像も変更せずに画像をグレースケール表示させる

Ads

ちょっと調べ物をしたのでメモ。
画像1枚だけで、グレースケール、
マウスホバーでカラー画像に、
みたいなのを実装したい、出来れ
ばJavaScriptも使用せず、みたい
な内容です。

2枚用意しろよと言われたら実も蓋もないんですけど、画像1枚だけでグレースケール⇔カラー画像を実装したい。画像の数は半分で済むし、加工の時間も不要になるのは大きなメリットです。

1年前に同じ事をunformedbuildingアップデート版もありました)さんがやってますので合わせてどうぞ。

Sample


マウス乗せるとカラーになる、という良くあるホバーエフェクトですが、極力無駄を省きたい。画像が1枚で済めば、20枚必要なところが10枚で済むし、画像が追加されても加工したり、マークアップしなおしたりファイルをアップロードする必要がなくなります。

IE


IEはfilterプロパティ使えばいいですね。

img{
filter: gray;
}
img:hover{
filter: none;
}

※IE6は対応しない。

Chrome


-webkit-filterプロパティでグレースケール化できる。

img{
-webkit-filter: grayscale(100%);
}
img:hover{
-webkit-filter: grayscale(0%);
}

-webkit-filterはSafari(5.1.7)では対応してないけど5.2から対応するみたい。iOS Safariもまだ対応してないのでiPhoneでは実装出来ませんでした。でも、タッチデバイスでのホバーエフェクトはユーザビリティを損なう可能性が高いので個人的には推奨しません。

Firefox


3.5以上。filterプロパティを使います。svgでフィルタを作り、そのsvgをDataURIで書いてURLとして指定。

img{
filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale");
}
img:hover{
filter: none;
}

:hover処理はIEと同じですね。
参考:SVG as Data URI for background image

Opera

canvas等を利用しないとダメっぽいですね。可哀想だけど諸々の理由から対応しない方向で。どうしても対応したい場合はHTML5 Grayscale Image Hoverという記事が参考になりそうです。

ゴール

img{
-webkit-filter: grayscale(100%);
filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale");
filter: gray;
}
img:hover {
-webkit-filter: grayscale(0%);
filter: none;
}

割とエコなのでは。​

雑感

多少のブラウザの犠牲がコンテンツの目的や目標に影響しないようなら個人的にはクライアントワークでも提案はすると思います。どうしてもクロスブラウザで、という場合はJavaScriptで対応すればいいですね。GRAYSCALE.JSとか良さそうでした。

via:Convert an image to grayscale in HTML/CSS