雑記: PNGと透過とレガシーブラウザ – 2013年秋
この記事は賞味期限切れです。(更新から1年が経過しています)
最近になってIE6のサポートは減ってきましたが、IE8の息もまた長そうですね。 透過PNGについては以前も記事をしたためた事がありますが、 当時からまた事情も変わってきてると思いますので、ここに昨今の対応に関する雑記などを記しておきます。
- 前提
- ここで言う「belatedPNG」は本家ではなく、
本家をフォークしている「jquery-belatedpng.js」を指しています
「おおきくくずれなければいい」IE6対応
「IE6ではおおきくくずれなければいい」
最近よく聞くようになってきたフレーズですが、つまり「完全にあわせなくてもいいけど一応見えるようにしてね」という事で、 見た目をある程度損なっても許容されるわけです。(と好意的に解釈しましょう。)
ところで、今IE6を使うような人達は、おそらく諸事情があって「致し方なく」使っていて、 きっとそういった方々はWebページで多少の劣化が見られても「致し方なく」思うのではないでしょうか。
そんな前提の元、レガシー環境への対応としては欠かせない透過PNGの話を少々。
IE6対応に8bit PNGを採用する
IE6での透過PNG対応には、8bit PNGという強い味方がいます。 多少見た目を損なってしまうものの、きちんと透過出来るようになります。 実際にどのように見た目が変わるかというと…
上が普通のブラウザで表示した8bitの透過PNGです。 わかりやすく背景にタイル状の画像を敷いています。
上が同じ画像をIE6で表示させたものです。 半透過の部分を完全に透過させて表示してしまう為、薄く敷いたドロップシャドウが消えたり、 エッジがギザギザになったりしています。細めの文字などで使用するのは結構厳しそうですが、 画像を選べばきちんと内容は伝わりそうです。
8bit PNG制作に便利なpngquant
pngquant — lossy PNG compressor
pngquantはコマンドラインでPNGを8bitに変換し、最適化する為のツールです。 IE6対策としても有用ですが、PNGを省サイズ化する上でも非常に便利なアプリケーションです。 GUIツールも配布されているので、「黒い画面」が苦手な方は試してみても良いかもしれません。
GUIツールでは、最近は ImageAlpha がよく知られているようです。 最適化時にpngquant以外のツールも選択できる優れ物です。
コマンドラインで pngquant を使ってみる
ここではコマンドラインでの使い方に軽く触れましょう。
$ pngquant img/foo.png --iebug
上の処理は、最適化された “img/foo-ie-fs8.png” という画像を新たに出力します。 “–iebug” というオプションは、PNGの「ほとんど非透過」の部分を非透過にするので、エッジの劣化を少し抑える事が出来そうです。
接尾辞を付けずに同名で上書きを行いたい場合は、“–ext” オプションと “–force” オプションを使います。 大事な事なのでもう一度いいます。同名ファイルとして上書きします。用法を守って正しくお使いください。
$ pngquant img/foo.png --iebug --ext .png --force
“img/” ディレクトリ内のpng画像をすべて処理したい場合は、ワイルドカードや find コマンドを併用したりします。
$ # img内のPNG画像を全て処理 $ pngquant img/*.png --iebug --ext .png --force $ # img内のサブディレクトリも再帰的に全て処理 $ find img/ -name "*.png" | xargs pngquant --iebug --ext .png --force
GUIではなくCLIを推したのは、クロスプラットフォームである点と、 みんなだいすきな Grunt と連携が取りやすいからです。
フィルタを通した8bit PNG
ちなみに、IE6で8bit PNGをAlphaImageLoaderを通して表示させても見た目は変わりませんが、 VMLのフィルタを通して表示させるとモダンブラウザと同様に綺麗に表示されます。 ある箇所だけ綺麗に見せたかったりする場合は部分的にbelatedPNG等を使用しても良いかもしれません。
opacityを変更した際の黒フチの問題
IE7-8で起こるこの現象については以前にも触れましたが、 結局のところAlphaImageLoaderやVMLに頼らざるを得ません。 両者にはそれぞれ特徴があるので、状況によって上手く使い分けましょう。
特に、肝となる透明度の調整で、二者はまったく違う挙動をするので注意が必要です。
AlphaImageLoaderへの透明度設定は親要素で
AlphaImageLoaderをあてた要素に直接 opacity を設定しても動きはするのですが、 ズームを変更すると表示に不具合が生じます。
.demo {
...
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(
sizingMethod=scale, src='sample.png') alpha(opacity=50);
background-color: transparent;
}
上のようなスタイルをあててIE8以下でブラウザのズームを弄ると再現できると思います。 条件は恐らくこんな感じでしょうか。
- AlphaImageLoaderとalphaのフィルターを同じ要素にかけている
- その要素のbackground-colorが指定されていないか、transparentだ
- ブラウザのズームが100%ではない
ズームをいじった状態でフェードイン・アウトなどをかけるとやられてしまいますので、 透明度を弄る場合は親要素に対して行った方が良いでしょう。
belatedPNG(VML)への透明度設定はその要素で
AlphaImageLoaderと違って、どうやらVMLは親要素の透明度を継承しないため、 fixPng() をあてた要素そのものに透明度を設定してあげなければいけません。
<div class="holder">
<img src="foo.png" alt="" />
</div>
<script>
$(".holder img").fixPNG();
$(".holder").css("opacity", 0.5); // 画像の透明度は反映されない
$(".holder img").css("opacity", 0.5); // 反映される
</script>
ブロックまるごとフェードインなどしたい場合は一工夫必要ですね。 楽に一工夫する方法は、また別のお話。
一旦まとめ
belatedPNGについてもう少し掘り下げる予定でしたが、 長くなりましたのでエントリーを分けることに致しました。
つづきはこちらで。 » belatedPNGと幸せにくらす為の小さなコツと小技
追記
- 2013/09/30 22:57
- 「-ms-filterの指定は不要では」と助言を頂いたので、該当箇所を削除しています。
cf) 佐祐理ブログ: -ms-filterは無意味
コメント