半透明ボックスに関するメモ
※2008年2月8日、IE6でinputボタンが押せない件について追記しました。
半透明ボックスに関してのメモ。
デザイナからの要望はこんな感じ。「よくあるタイプのコンテンツ部分の背景に単色ベタの土台を置くようなデザインじゃなくて、今回は背景画像を活かしたデザインにしたい、テキストやら写真やらの中身を入れるボックスだけ半透明にして見せたい背景画像をうっすら表示させたい。」
今回やっかいだなと思ったのが、コンテンツ部分が全面そういう風に背景の上で半透明になっているのではない点。タイトル画像が入る部分やそれぞれのセクションの余白部分は半透明ではなく、素の背景が見えるというもの。文章にするとややこしい・・・つまりこんな感じ↓。(背景とか色合いとか変だけどあくまでサンプルだから気にしないでください・・・。)
半透明のボックスって中身も半透明になるんだよね
CSSだけでボックスを半透明にする方法は以前このブログでも書いたんだけど(CSSで半透明ボックス)、opacity辺りで透明度の指定された親をもつ子要素って、みんな半透明になる。こいつが今回の困った部分。divを入れ子にして透明度100%を指定しても結局親の透明度を継承してるから意味なし。
透過pngさえ使えたら特に問題ないんですが、IEさんがアレなので、とりあえずCSSだけでやるにはどうしたらいいかを考えました。
方法その1・画像で入れる
まず思いつくのが「半透明のボックスの背景画像で切っちゃえばよくね?」の案。だけど文字サイズが可変された場合なんかに背景がついてこない事になる。大きめに画像を切ったとしても一番上はいいけど、2番目以降の背景は下にズレこんでくる。ビミョー。
方法その2・画像で入れて overflow は?
方法その1に加えて高さが変わったときはスクロールするようにすればいいんじゃね?という考え。それならボックスの大きさ自体は変化しないし、背景がズレこむこともない。だけど「背景画像に拘りたいの!」と言ったデザイナからすればこんな所にスクロールバーがでるのはすごく嫌な事だろうな、と。
まぁ高さや幅が変わらなければそれはそれでいいんだろうけど、スクロールバーの発生に備えて、横スクロールが出るのは勘弁だぜってことで右側の余白も確保したり元デザインから幅もコントロールしなきゃならなくなったり、厳しいデザイナに「1pxでもズレたら許さないんだから!」とか言わせたくないし。ビミョー。
方法その3・禁断の空div
個人的には禁断の「空div」で半透明部分を確保する方法。lightboxなんかで画面全体をオーバーレイさせてその上にボックスを置いているのも確かこの方法だった気がする。幅、高さ、透明度なんかを指定した空divに対して position で浮かせて位置、透明度を指定して、その上にさらに中身の入ったボックスを重ねて半透明を実現させる。
この方法も中身の高さが変化した際にはCSSだけでは対応できない。というか、いちいち位置を指定するのがものすごくめんどい。非効率すぐる気がする。こういうのは使うなら絶対大きさも場所も変わらない箇所に限定しなくては。。。
方法その4・やっぱりここは javascript ですか
上の3つの案はCSSだけでっていうのが前提なんだけど、要するに透過PNGさえ使えたら何も問題ないわけですよね、バリデータ通らないCSSのプロパティ (opacity 関連)も使わなくて済むし。ということで。IEさんでも透過PNGが使えるように、javascript を利用してなんとかする作戦。
ちょうどさっき jQuery 関連でこんな記事をお見かけしたのでさっそくテストしてみる。
>>jquery.pngFix.js - PNG transparency for Windows IE 5.5 & 6 (IE PNG Fix)
簡単設置で非常に便利。jQuery万歳。
>>jQuery と jquery.pngFix.js を使ったサンプル
これが一番効率いい。IEで js 無効の場合でも半透明にならないだけで、可読性の面では問題ないぞ、と。下記のキャプチャはIEでjs無効の場合のサンプルです。
設置は jQuery 本体と上記 jquery.pngFix.js を head 内で読み込んで、その後ページの読み込みと同時に半透明を使いたいボックスに対して pngFix を有効にしてあげるだけ。あとは普通にcssで問題のpngを背景として指定すればいいだけです。
<script type="text/javascript" src="../js/jquery.js"></script>
<script type="text/javascript" src="../js/jquery/jquery.pngFix.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('div#sample').pngFix( );
});
</script>
#sample{
width:640px;
height:427px;
background:url(img/071201_01.jpg) no-repeat;
}
.contents{
width:420px;
background:url(img/071201_02.png);←ここでPNG使ってる
}
<div id="sample">
<h2>サンプルタイトル</h2>
<div class="contents">
<p>テストテストテスト</p>
<p>テストテストテスト</p>
</div>
<h2>サンプルタイトル</h2>
<div class="contents">
<p>テストテストテスト</p>
<p>テストテストテスト</p>
<p>これで内容量や文字サイズが変わっても大丈夫かな。</p>
</div>
</div>
pngを使いたい箇所毎に個別に指定をするわけではなく、該当範囲の親に対して指定をすればそれで済むというのがすごく気に入りました。透過pngを古いIEでもサポートできるようなjsライブラリはいろいろあるけど、個人的にはこれが一番楽でした。
IEでinputボタンが反応しない件の対処法
コメント欄にてこのjsを使った場合、IE6でそのボックス内に配置したinputボタンがクリックできない、という現象について教えていただきました。
一応inputタグとbuttonタグ、両方で試してみたところ、どちらもIEではボタン上にマウスが乗っても感知せずクリックできない感じになってます。(但し各ボタン下の方4分の1くらいの高さ部分を狙うとクリックできるという感じ)
対処方法なんですが、inputやbuttonに対してposition:relative;を指定してやるとボタン全体がクリックできるようになりました。
IE7の方ではpositionを与えなくても、ちゃんとクリックできるっぽいです。
<< IE7のフォント絡みでこんな話があった | overflow を使用したボックス背景のこと >>
トラックバック
このエントリーのトラックバックURL:
http://redline.hippy.jp/cgi/mt/mt-tb.cgi/175
コメント (9)
使ってみたところ、IE6のみ透過pngをバックグラウンドに指定している場合、その上にinputのボタンをおいても、ボタンがおせないようです。
投稿者: 匿名 | 2008年02月08日 11:30
>匿名さん
教えていただいてありがとうございます!
inputをそこに置くのは試したことなかったんで実際やってみました。
http://redline.hippy.jp/redline_sample/0712/sample_js2.html
(;゚д゚)ァ....
ほんとですね。IEだとボタン感知しない・・・と見せかけて下半分、いや下4分の1くらいのエリアだけ感知してクリックできる、みたいな反応してますね。なんだこれは・・・(汗)
ちょっといじってみたんですが、こうするとうまくいくみたいです。
http://redline.hippy.jp/redline_sample/0712/sample_js3.html
input,buttonなんかにposition:relative;を指定するとちゃんとクリックできるようになりました。とりあえずこれで押せない状態は回避できるのでは・・・と思います。
投稿者: Red | 2008年02月08日 11:56
こんばんは^^IE6のpng画像表示で困っていたところたどり着きました。
触れてないので難しい事なのかもしれませんが外部CSSで
指定した背景画像(png形式)に対応することは
出来ないものでしょうか?
本家のサンプルをダウンロードしてみたのですがhtml内に
記述したCSSには対応できるようなのですが外部CSSで
指定したpngにも対応できると素晴らしい限りだと思うの
ですがこのような事は可能でしょうか?
宜しくお願い致します。
投稿者: くーる | 2008年02月12日 03:03
>くーるさん
あれれ。外部CSS内に記述したpng画像、半透明にならないですか?
ちょっと上のサンプルページで外部のCSSからpng背景を指定したページを作ってアップしてみました。(↓)
http://redline.hippy.jp/redline_sample/0712/sample_js4.html
うちのIE6では透過になってるんですが、くーるさんのお手元ではいかがでしょうか?
投稿者: Red | 2008年02月12日 22:18
お返事ありがとうございます!
サンプルページを見る限りでは綺麗に透過されている状態
で確認できます。
サンプルページと自分のhtmlを確認し微妙な違いを発見し修正してみました。
(誤作動防止のため、一部を全角で記載します。)
/*1 - htmlでのjsの読み込み*/
・変更前
<SCRIPT type="text/javascript" src="js/jquery.pngfix.js"></SCRIPT>
・変更後
<SCRIPT type="text/javascript" src="js/jquery.pngFix.js"></SCRIPT>
・修正ポイント
ファイル名はjquery.pngfix.jsのままですがhtmlの読み込みにはfをFと変更
/*2 - htmlでのjsの実行*/
・変更前
<SCRIPT type="text/javascript">
$(document).ready(function() {
$("img[@src$=png]").pngfix();
});
</SCRIPT>
・変更後
<SCRIPT type="text/javascript">
$(document).ready(function(){
$('#sample').pngFix( );
});
</SCRIPT>
・修正ポイント
function実行のfをFに変更。しかしこのままでは
動作しなかったのでbodyにidを振ったところ
なんとか正常に動作確認できました。
本家のサンプルhtmlを参考にしてたので間違っている
ことはないと思うのですが何故動作しなかったのかは
謎です・・・^^;
投稿者: くーる | 2008年02月12日 23:45
>くーるさん
あーよかった。うまく動作されたんですね。
img要素の中でsrcの値がpngで終わるものっていう指定ですよね?
属性セレクタのimg[@src$=png]の部分を、img[@src$=".png"]という風に「""」で「.png」という値を括ってやったらどうなるかな、とか思いました。E[foo$="bar"]の属性値の指定には""がいると思うので多分jQuery型のE[@foo・・・の方でも値には""がいるかな、と。
あと、私の方のソースでfがFになってるのは単にDLしたファイルの名前が大文字だったからっていうだけですー。
投稿者: Red | 2008年02月13日 00:10
$(document).ready(function(){
$("img[@src$=".png"]").pngFix();
});
として検証してみたところやはり無理でした・・・
>私の方のソースでfがFになってるのは単にDLしたファイルの名前が大文字・・・
試しに読み込み,実行のFをfとしてみたのですがこちらも
動作しませんでした。
やはり謎です・・・w
しかしながらおかげさまで動作させることができたので
助かりました^^
また遊びにきますね!
投稿者: くーる | 2008年02月13日 02:24
>くーるさん
ダメでしたか・・・><
お力になれなくて申し訳ないです。
あ。
$("img[@src$=".png"]").pngFix();ってエラー出ませんでした?
$('img[@src$=".png"]').pngFix( );ならエラーでないと思うんですが・・・。いや、検証してないんでわからないですけど・・・。
まぁ、でも別の方法でも意図した内容を描写できたならよし、ですかねw
また遊びに来てくださいましー。
投稿者: Red | 2008年02月13日 12:22
このjavaScriptを使わせて頂きましたー♪
くーるさんと同じような問題で、bodyにID振ってやったら動きました。CSSを動的に作成しているのが問題なのかもしれません。
ちなみに、cakePHP 1.2を利用しています。
ありがとうございましたー♪
投稿者: caakee | 2010年09月30日 16:45