半透明についての調査結果

ホームページを作るにあたって、半透明がなかなかできなくて、調べまくったところ、実はすごく難しいことが発覚した。一部にバグを利用しないといけなかったり、非常に不安定だ。

次世代のブラウザだと、rgba形式の色指定が広範囲に採用されるため、問題ないが、現行ブラウザの多くは微妙な調整が必要になる。主にCSSで調整することになるが、ブラウザ別のCSS選択は、バグもどきで全く美しくない。俗にCSSハックと呼ばれている。さらに、次世代ブラウザまで考慮したとき、CSSハックは不完全であることがわかった。

だから、phpを使って動的にCSSを調整するしか手はないという結論に至った。

SERVER["HTTP_USER_AGENT"]の値

operaOpera/9.63 (Windows NT 5.1; U; ja) Presto/2.1.1
firefoxMozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5 (.NET CLR 3.5.30729)
safariMozilla/5.0 (Windows; U; Windows NT 5.1; ja-JP) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/525.27.1
chromeMozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/1.0.154.43 Safari/525.19
IE7Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
IE8Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0 ....(という噂)
opera 10Opera/10.00 (Windows NT 5.1; U; en) Presto/2.2.0(アルファ版で確認

半透明対応状況

ブラウザRGBAOpacityPNG
IE7××
chrome
firefox
safari
opera××
IE8×(*)
opera 10

(*)一般にはIE8はRGBA対応と言われているが、Windwos7Beta版のIE8ではRGBAは対応でなかった。RC1はアンインストールに難があるということなので、試せていない。ふたを開けてみると対応ではなかった。UserAgent情報を使うとすると、レンダリングエンジンの細かなバージョンのみがRGBA対応状況を知る手がかりであり、はっきり言って泥沼である。

PNGは最近半透明情報を保持した画像をコーディングできるようになった。しかし、すべてのブラウザが半透明PNGに対応しているわけではない。というか、むしろ、現行ブラウザはダメで、次世代でようやくOKになるらしい。

半透明PNGは、Paint.NETなどで作成できる。GIMPは未対応。

結局、Mozilla/5.0系はRGBAに対応していて、Mozilla/4.0は対応していない、とまとめることができる。background-color:white;をbackground-color:rgba(...);で上書きすると、rgba未対応環境ではbackground-color:inherit;に戻されるらしい。逆順はrgba対応環境で意味なし記述になるので、使えない。結局、二択にしないといけないということだ。

IEでは、filter:alpha(opacity=xx)でopacityと同じ効果が得られる。また、おそらくバグで、imgに対して、position:relativeを指定するとfilter:alpha(opacity=xx)をキャンセルできる。つまり、写真は半透明にしない、という風にできる。

opera9では、IEのようなキャンセル技がないので、写真を半透明から救えない。だから、半透明をあきらめたほうが良い。これはIE以外のMozilla/4.0ブラウザ全般に言えることだと思われる。

opera9ではなぜか正常なレンダリングができないらしい。理由は不明だが、CSSを重ね書きしているからかもしれない。

最終的なデザイン

PHPで_SERVER["HTTP_USER_AGENT"]による振り替えを行うが、3種類用意する。

type検出法code備考
IE7MSIE7.0body {
background-color: white;
filter:alpha(opacity=85);
}
img {
position:relative;
}
文字も半透明になるので、少し手加減する
Mozilla/5.0Mozilla/5.0body {
background-color: rgba(255,255,255, 0.8);
}
IE8MSIE8.0同上
Opera 10Opera/10.同上
その他その他body {
background-color: while;
}
半透明になった写真はかなり違和感があるので半透明自体をやめる

挿入コードは以下のようになるだろう。

body {
  .....
 <?php
  if(strpos($_SERVER["HTTP_USER_AGENT"], "MSIE 7")!==false) {
    echo "background-color: white;filter:alpha(opacity=85);";
  } elseif(($_SERVER["HTTP_USER_AGENT"], "MSIE 8")!==false) {
    echo "background-color: rgba(255,255,255,0.8);";
  } elseif(($_SERVER["HTTP_USER_AGENT"], "Mozilla/5")!==false) {
    echo "background-color: rgba(255,255,255,0.8);";
  } elseif(($_SERVER["HTTP_USER_AGENT"], "Opera/10")!==false) {
    echo "background-color: rgba(255,255,255,0.8);";
  } else {
    echo "background-color: white;";
  }
?>
}
img {
  ....
 <?php
  if(strpos($_SERVER["HTTP_USER_AGENT"], "MSIE 7")!=false) {
    echo "position:relative;";
  } 
?>

こんな感じ?

連想記憶は時間がかかるだろうから、$UA=$_SERVER["HTTP_USER_AGENT"];としてやるかな。

方針転換

IEでopacity+画像半透明キャンセルという技で満足のいく表示が得られるのだが、動作が極端に遅いということが判明した。最近のPCではOKだが、非力なPCでは目に見えて遅い。グラフィックスまわりのスピードが効くのだと思われる。なので、IE7での半透明は行わないことにした。

UserAgent方式は数あるブラウザのバージョンアップについていかないといけないので、気が狂いそうだ。例えば、WebKitは525.xxからRGBAをサポートしているが、すでに529.xxというバージョンが存在する。バージョンチェックスキームをかなり工夫しないといけないだろう。

いろいろ調べて、JavaScriptでRBGAが実装されているかどうかチェックすることにした。

まず、RGBAをセットしてみて、JavaScriptで検証し、実装されていればRGBAを使ってbodyとmenubarのbackground-colorを設定することにした。

<script type="text/javascript">
<!--
function CheckRGBA() {
	var color = document.getElementById("rgbacheck").style.backgroundColor;
	var out=document.getElementById("out");
	if(color == "" ) {//--------------------------------------------------------NO-RGBA
		out.innerHTML+="no RGBA<br>";
	} else {//------------------------------------------------------------------RGBA-READY
		out.innerHTML+="RGBA capable<br>";
		  document.getElementById("body").style.backgroundColor="rgba(255,255,255,0.8)";
		 document.getElementById("menubar").style.backgroundColor="rgba(255,255,255,0.8)";
	}
}
// -->
</script>
</HEAD><BODY background="./TK_files/bubbling.jpg" onload=CheckRGBA()>
<div id="rgbacheck" style="background-color:rgba(255,255,255,0.5);"> </div>
<div id="out"></div>

ローカルファイルでのテストで、LunascapeのWebKitエンジンではCSSが全くロードできていなかったが、サーバーからは大丈夫だと思う。IE/Gecko/WebKit/Operaの主要4大Webレンダリングエンジンで同一コードが動作することから、おそらく現在のところ、もっとも確実なRGBA実装チェックだと思われる。


Last-modified: 2010-09-06 (月) 15:43:45 (3698d)