IEの透過PNG+opacityの不具合を治すメモ
この記事は賞味期限切れです。(更新から1年が経過しています)
透過PNGの処理が下手くそなのは、IE6だけではなく、IE7/8も同様です。
IEで透過PNGをあてた要素のopacityを弄ると、周りがグレーがかって汚くなります。
この現象はよく知られていると思いますが、今日はこの不具合の治し方のメモを記しておきます。
サンプルコード
例えば、こんなコード。
<style>
.test {
display:block;
width:128px;
height:128px;
background:url(./test.png) 0 0 no-repeat transparent;
}
.test:hover {
background-image:url(./test-hover.png);
}
</style>
<a href="#" class="test"></a>
test.pngとtest-hover.pngは透過PNGです。
IE6では当然透過されずに背景がグレーになります。
IE7,8では綺麗に表示されている様子ですが…
$(".test").css( "opacity", "0.5" );
このようにfilterのopacityを弄ってやると、下記の画像のような状態になります。キタナイ。
DD_belatedPNGはどうか
上記の現象はalphaImageLoaderを使えば解決出来るのですが、
alphaImageLoaderはhover時の処理が面倒だったり、遅かったりと問題もあります。
そこで去年ぐらいからもてはやされているDD_belatedPNGを使ってみましょう。
DD_belatedPNG: Medicine for your IE6/PNG headache!
DD_belatedPNGは他の透過PNG用ライブラリと異なり、
alphaImageLoaderを使わずにVMLで透過を実現しているのが特徴。
パフォーマンスも比較的上々のようです。
IE8でエラーが出る
が、困ったことにIE6向けのライブラリであるが為か、
IE8で走らせようとするとエラーが出ます。
今回のお題はIE6~8全てに関わる物なのですが、困りました。
jQuery移植版を使用する
探してみたところ、DD_belatedPNGをjQueryプラグインとして移植した記事を発見。
そこらへんの問題も解決してくださったみたいです。素晴らしい!
- 該当記事
- DD_belatedPNG を改造して、jQuery.belatedPNG を作ってみた | プログラマ気分
- リポジトリ
- wakuworks/jquery.belatedPNG – GitHub
jquery.belatedPNG.jsで試してみよう
jquery.belatedPNG.jsは、
jQueryオブジェクトにfixPng()メソッドを提供します。
こんな感じにしてみる。
$(".test").fixPng().css("opacity","0.5");
opacityを設定しても汚くならない!素晴らしい!
マウスイベントが効かなくなる問題
ただ、このままだとa要素に対するマウスイベントが効かなくなってしまう模様。
CSSで設定した:hoverのスタイルも適用されず、
クリックしてもウンともスンともいいません。
なので、子要素に「透明な何か」を入れてあげる事で解決を試みます。 例えば透過Gif。
<a href="#" class="test">
<img src="trans.gif" width="128" height="128" alt="Foobar" />
</a>
これでマウスイベントがきちんと効くようになりました。
hoverのスタイルも適用されます。
もしくは、同サイズの透明要素を中にappendしてやったり。
var $test = $(".test");
// opacityに非対応なブラウザに適用
if( !$.support.opacity ){
$test.fixPng()
.append(
$("<span>").css({
display : "block",
width : $test.width(),
height : $test.height(),
backgroundColor : "#ffffff",
opacity : 0,
cursor : "pointer"
})
);
}
$test.css( "opacity", "0.5" );
まとめ
jQueryのプラグインでfadeIn/fadeOut等を使うとopacityが弄られますが、
その影響でこの不具合に遭遇する事があるので注意したいですね。
マウスイベントの件は、他に良い解決策あったら知りたいです!
コメント