IE6で半透明PNG
InternetExplorer7、Firefox、Opera等の現世代(もう次世代ではないよね?)ブラウザは半透明のPNG(PNG内のαチャンネルで透過の割合をピクセルごとに設定できるPNG)に対応している。これを背景やボタン画像に使用すると表現の幅がかなり広がる。
しかし、2008年夏現在、シェアがトップであると思われるInternetExplorer6ではこれに対応していない。WebデザイナーのためのIE6で何とかする方法のメモ。
キモ
結局のところ、CSSのIE独自拡張であるfilterで、
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='trans.png',sizingMethod='scale');
などとしてやれば一応αチャンネル対応になる。
しかし、話はそう単純でなく、
- イベント(マウスオーバー等)により、画像を差し替えた場合に透過が効かなくなる。
- リンクが貼られている画像の場合に、そのリンクが無効になる。
- background-imageに使用した場合に、positionやrepeatが効かなくなる。
などの問題があるらしい。
TwinHelix IE PNG Fix
で、結局のところ、筆者(立花柑)はTwinHelixのIE PNG Fixv1.0RC4を使用している。特にどこがよいというわけではないのだが、他のサイトで配布のものは、上記の制限を緩和するために若干使用方法がわかりにくかったというだけの理由。逆に言うと、このTwinHelix版が必ずしも上記制限を回避できているわけでもない。
[CSS] .alphaback{ background-image: url('trans.png'); behavior : url('iepngfix.htc'); } [HTML] <div class="alphaback">背景にtrans.pngが適用される文章</div>
というように使用する。
筆者はHTCに詳しくないので全容はよくわからないのだが、わからないなりにiepngfix.htcの中身を覗いてみると、HTMLのIMGエレメントとCSSのbackground-imageに対応しているようだ。IMGの場合には付属のblank.gifを一緒に使う必要がある模様。
background-repeatが効かない問題は、The easiest way to PNG support in IE6にある条件化での解決策が示されている。iepngfix.htcを改造し、画像をコンテナ(div等)のサイズにリサイズすることで、単一色ベタ塗りPNGの場合にはある程度、見た目上の問題が解決できる。「ある程度、見た目上」というのは、ベタ塗りでない場合に画像自体が拡大される(repeatされるわけではない)ことと、ウィンドウのリサイズによってコンテナサイズが変わった場合に追従しない点を指している。
その不完全な改造方法を示すと、
style.backgroundImage = 'none'; if(currentStyle.backgroundRepeat == 'repeat') filt(s, 'scale'); else filt(s, 'crop'); // IE link fix.
というように、オリジナルではcrop(切り取り)が指定されているところを、CSSでbackground-repeat:repeatとされている場合にはscale(サイズ伸縮)を指定するように変更する。つまりCSSを、
.alphaback{ background-image : url('trans.png'); background-repeat: repeat; behavior : url('iepngfix.htc'); }
と、一見それらしく書けるようになる。
ライセンスはLGPL v2.1以降となっているが、このようなWebパーツの場合に、LGPLがどのように適用されるべきなのかは若干謎だ。使用するだけなら基本的には再配布ではないので、特段制限を受けないと理解しているが、制限を受けたとしても、WebでのHTCの利用=ソースを再配布しているので、既に条件は満たされているはずだ。
なお、上記はv1.0RC4に限った話で、現在出ているv1.0正式版や、position/reapeatをサポートするというv2.0については色々異なる可能性が高い。v1.0RC4とv1.0は(RCだったにも関わらず)大幅にコードが変わってるので注意されたい。ヒマを見つけたら、またそれらバージョンでの使用方法も検証したい。
その他のIE6で半透明PNG対応に関するネタ
- ユンサンの透過PNG と IE と IE7 まとめ(TwinHelixの改造版)
- ユンサンのIEPNGFIX の Tips 1 改訂版 + バージョンアップ(リンク貼ってる場合の対処)
- アルファ画像を扱うalphafilter.jsライブラリ
追加メモ(2008/07/28)
しばらく上記iepngfix.htcのv1.0RC4で使用していたところ、透過PNG背景を適用したブロック要素の子要素でリンクが効かない、フォームに入力ができないなどの問題が発生することがわかった。必ず発生するわけでもないのだが…。
具体的に言うと、
<div style="background-image: url('trans.png'); behavior: url('iepngfix.htc');"> <table><tr> <td><a href="〜"><img src="〜" /></a></td> <td><input type="text" /></td> </tr></table> </div>
といったソースで、画像がリンクでないかのように振る舞い、フォームはクリックしても入力カーソルさえ表示されない。
この問題は日本語圏のネット上ではhoverが動作しない問題として報告されているようだが、より的確な表現としては、「iepngfixを適用した要素(エレメント)に透明レイヤーがかかったようになり、表示は正しいがユーザが子要素の操作をできなくなることがある」と言ったほうがいい。
これを英語圏で調べてみると、いくつか報告が上がっている。が、向こうでも結構混乱しているらしく、なかなかその条件や汎用的な解決方法が示されていない。まず比較的詳しいのはsatzansatzで、iepngfix要素のpositionと子要素のposition、そしてz-indexが関わってくるらしい。
satzansatzはDALTONLP.COMを参照しており、ここではPNGの画像サイズによる、というような記述もあるが、これは妥当とは思えない。そして、上のほうで言及したThe easiest way to PNG support in IE6が決定版なので参照するようにとなっている。戻ってきてしまった。
で、もう一度よく読むと、コメントでIE AlphaImageLoader, Transparent PNGs & Linksが示されており、ここで言われる解決方法は以下の通り。
- iepngfixを適用した要素のpositionは何も指定しない。
- 子要素のpositionはrelativeにする。
結局これが、一応の汎用的な解決方法だ。ただし、positionの指定に自由がない。どうしてもpositionを変更したければ、さらにpositionのための要素を追加し、入れ子にする必要がある。
そして筆者が試してみた限りでは、上記の例で挙げた「div(iepngfix)→table→tr→td→対象の子要素」の例は解決できなかった。直接の子要素でないことが関係しているのか、tableのような置換要素が関係しているのかはわからない。
最終的に、不本意ながらtableをiepngfix適用とすることでリンクを貼った画像もフォームも動作した。このことからすると、入れ子の深さよりも置換要素であることの関係が有力ではある。しかし、結局子要素にposition:relative;もz-index:1;も指定せずに直ってしまったので、そもそも上記議論のケースとは外れているかもしれない。
結局発生条件も明確ではなく、修正方法も万能ではない。場当たり的に直すしかないのはhackであることの代償だろうか。
最終更新時間:2008年07月28日 02時38分14秒