IE9、不透明度、アルファ

本記事は、マイクロソフト本社の IE チームのブログから記事を抜粋し、翻訳したものです。
なお、本記事中の Internet Explorer 9 は、元記事執筆当時の ( 正式リリース以前の) ものについて記載しておりますのでご了承ください。

【元記事】 IE9, Opacity, and Alpha (2010/8/17 6:15PM)

IE9 では、CSS3 カラー モジュール (英語) と、よく使われるその不透明度プロパティがサポートされるようになりました。他の標準ベースの機能と同様に、不透明度が実装されることで、他のブラウザーで使用されているマークアップが IE9 標準モードでもそのまま動作します。

IE8 以前のバージョンでは、IE 固有のフィルター プロパティのアルファ フィルターを使用して不透明度を適用する代替メカニズムが実装されていました。IE9 標準モードでは不透明度だけがサポートされ、アルファ フィルターはサポートされないため、互換性の問題が生じます。(IE9 の Quirks モード (互換モード)、IE7、および IE8 では、アルファ フィルターはサポートされますが、不透明度は実装されていません。)

ベスト プラクティスである機能検出を使用するサイトでは、これは問題になりません。それらのサイトは、IE9 が不透明度をサポートしていることを検出して、フィルターの代わりに不透明度を使用します。問題はブラウザー検出を使用するサイトです。このようなサイトは、IE が常に不透明度の代わりにアルファ フィルターを使用するものと誤って判断し、スクリプトでフィルター プロパティだけを変更します。そのような Web ページの不透明度エフェクトは、IE9 既定の IE9 ドキュメント モードで実行されると、正しく表示されません。修正方法としては以前の記事 (英語) で説明したように、最初に標準ベースの不透明度機能を検出し、次にブラウザー固有のフィルター機能を検出します。

CSS のベスト プラクティスの例

 .fiftyPercentOpaque
{
    opacity: 0.5;
    filter: alpha(opacity=50);
} 
コードのベスト プラクティスの例
 // set flags for whether we should use opacity or filter with
// this browser (or browser mode). we prefer opacity.
var useOpacity =
   (typeof document.createElement("div").style.opacity != 'undefined');
var useFilter = !useOpacity
   && (typeof document.createElement("div").style.filter != 'undefined');

function setOpacity(el, value) {
   // let el be either an element object or an id string
   if (typeof el == 'string')
      el = document.getElementById(el);

   // ensure value is in [0-1] range
   value = Math.min(1, Math.max(value, 0));

   // set opacity or filter alpha depending on what's supported
   if (useOpacity)
      el.style.opacity = value;
   else if (useFilter)
      el.style.filter = "alpha(opacity=" + (value * 100) + ")";
}
代替のブラウザー検出コード

通常は、ブラウザー検出よりも機能検出の方が推奨されますが、不透明度に関するコードでは機能検出ではなくブラウザー検出がよく使用されています。現在のサイトでそのような処理を行っている場合は、IE9 を適切に処理できるように既存のブラウザー検出のコードを修正する方が簡単かもしれません。次のコードは、IE が IE9 標準モード以外のブラウザーのモードで実行されている場合、そのことを適切に検出します。

 function browserDetectSetOpacity(el, value) {
   // let el be either an element object or an id string
   if (typeof el == 'string')
      el = document.getElementById(el);

   // ensure value is in [0-1] range
   value = Math.min(1, Math.max(value, 0));

   if (navigator.userAgent.match(/\bMSIE\b/)
         && (!document.documentMode || document.documentMode < 9))
      el.style.filter = "alpha(opacity=" + (value * 100) + ")";
   else
      el.style.opacity = value;
}
まとめ

上で説明した問題は、フィルターの変更前に不透明度がサポートされているかどうかを検出せずにスクリプトで要素の不透明度を変更した場合にのみ発生します。宣言型 CSS マークアップだけを使用しているサイトは、要素の CSS クラスを変更したり、:hover などの擬似クラスを使用したりして間接的に不透明度を変更した場合でも、引き続き正しく動作します。

W3Schools (英語) では、CSS の不透明度および IE の従来のアルファ フィルターについて、詳しい説明 (英語) が提供されています。

—Ted Johnson、Web グラフィック担当プログラム マネージャー リード