読者です 読者をやめる 読者になる 読者になる

Paradigm Shift Design

ISHITOYA Kentaro's blog.

クロスブラウザな画像マスク手法(FadeIn/FadeOut可能)

最近、クロスブラウザで画像と動画にマスクをかけるという案件がありまして、IEに呪いの言葉をぶつけながら解決したので、そのメモです。

ちなみに私は、フロントエンドエンジニアではなく、バックエンドエンジニアでもなく、ただのプログラマなのでCSSまわりとかおかしいところあるかもしれませんが。

なお、当記事は、The Nitty GrittyというサイトのChristian Schaeferさんが書いたThe Nitty Gritty: CSS Masks – How To Use Masking In CSS Nowという記事をものすごく参考にしています。

はじめに

なにをしたいかは、マスクテスト (Masking Test Script)を見ていただければ分かります。
(サンプルの画像がなぜネコ科のアレかというと、Schaeferさんの記事があのネズミだからです)

つまり
「画像を2枚重ねて、上側の画像を任意の形にマスキングして透過し、下側の画像が見えるようにする」
ということで、あらかじめ画像を用意できればいいんですが、そうでない場合いろいろごにょごにょせにゃならんということで。
github:masking-testにコードがおいてあるので、サンプルのマスクテスト (Masking Test Script)と見比べながら読んでみるとよくわかると思います...

画像のマスキング

画像のマスキングそのものは、さっきのSchaeferさんの記事にあるようにやればOKです。
が、いくつかバグがあります…ブラウザの。

WebKit

WebKit様は、一行でかつ完璧です。完璧!素晴らしい!素晴らしい!

-webkit-mask-image: url('../images/mask.png');

InternetExplorer 7/8

なんとIE7/IE8ではこのまま問題なく動くんですねぇ。素晴らしい。
あ、素晴らしいのはSchaeferさんであって、IEではないです。

OSX FireFox

マスクテスト (Masking Test Script)をOSXのFireFoxで開いて、Ex1の「Click to Fade In/Out 」ボタンを押してもらえれば分かるのですが、フェードというかネコ科のロボットが消えていなくなると思います。ブラウザのサイズ変えたり、上にウィンドウをかぶせてもらえれば分かるんですが、再描画のバグですかね。ちなみに、Ex1はSchaeferさんのやり方でマスキングした奴です。

clip-pathとかいうCSSプロパティがつかえるというので…

clip-path: url('../images/mask.svg#mask');

とか書いたったんですけどね…
FireFoxはIE系と同じForeignObjectを用いたマスク方法が使えるので、それを適用したのがEx2です。 四次元ポケットネコがちゃんとFadeIn/FadeOutすると思います。

InternetExplorer 9

IE9だけ挙動違うとか...爆発すればいい!けどなぁ… IE9のマスキングは、

<div style="width:400px; height:400px; filter: progid:DXImageTransform.Microsoft.Chroma(color='#00FFFF'); zoom: 1;">
  <img src="images/image.png"/>
  <!--[if lte IE 9]><img src="images/mask_mozie.png" style="display: block; margin-top: -400px;"><![endif]-->
</div>

のようにするみたいです。

親にChromaフィルタを指定して、color='#00FFFF'で指定したシアンの部分を抜いた画像が出力されます。 iemask
mask_mozie.pngはこんな感じなんで、image.pngからシアン部分を抜いたものが表示されるわけで。

で、IE9からopacityが使えるようになったようですが、それが中途半端なようでEx1/Ex2をIE9で動かしてもらえれば分かりますが、opacityが変更されると、mask_mozie.pngの色も変わってしまい色が抜けなくなってしまうみたいです… opacityをimage.pngにかけてみても変わらないため、

filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=20);

でAlphaを調整しています。この方法だとopacityと違って色が抜けるのね。
ただ、IE9で動かしてみれば分かりますが、残念ながら今のところOpacity=0になったら消えるんじゃなくて黒くなるのね…CSS設定しても何も変わらないし、仕事ではバックグラウンドが黒くてセフセフでしたので、追求してません。
原因が分かる方いらっしゃいましたら教えてください…

おわりに

IE6…? 爆発しろ!なお、Operaとか試してません。

追記