CSSのみでIE6にposition:fixedを対応させる

カテゴリ:CSSテクニック 2009年3月16日 13:09

[2009/08/14 修正]
内容が若干分かりづらかったので加筆しました。全体的な内容は変わっていません。
[2009/03/22 修正]
サンプルの問題の修正に合わせて、記事を書き直しました。

今回は IE6 でも、CSS だけでposition: fixedを実現するテクニックです。
通常、IE6 ではposition: fixedをサポートしていないため、普通に指定するだけでは固定配置されません。

今回紹介するテクニックは、いくつかの IE6 のレンダリングの誤差を使って巧みに position: fixed を実現する方法です。
まずは以下のデモを IE6 で見てみてください。ちゃんと右下に固定配置されているのが分かると思います。

IE6 に position: fixed を適用させるデモ

大きく分けると、実現するための方法としての要点は 5 つ。

  1. 標準準拠モードで動作するよう、DOCTYPE 宣言を記述する。
  2. html, body 共に height: 100% を指定する。
  3. スクロール対策として、全体をくくる div 要素を追加する。
  4. 固定配置したい要素に対して position: absolute を指定する。
  5. 固定配置したい要素を、全体をくくっている div の外に配置する。

上記 5 点を踏まえて HTML、CSS を書くと以下のようになります。

▼EntryMore▼

HTML ソース

CSS ソース

標準準拠モードで動作するように設定

HTML 側のポイントは 2 つ。
まず、IE6 が標準準拠モードで動作するよう、xml 宣言をせずに、かつ適切に DOCTYPE 宣言を行います。
次に、他のブラウザには必要ないですがdiv#coverでコンテンツ全体(固定配置したい要素以外)をくくります。HTML での注意点はこれだけです。

CSS 指定時の注意点

続いて、CSS の注意点は 3 つ。
まず、html と body 要素に対して、height: 100%overflow-y: autooverflow-y: hiddenoverflow-x: hiddenoverflow-x: autoを指定します。
次に、div#cover に対してoverflow: autoposition: relativeを指定します。
width と height を 100% にしているのは、コンテンツをブラウザ幅いっぱいに広げるためです。
最後に、position: fixed を適用したい要素(サンプルでは fixedItem)に対して、position: absoluteを指定します。

なぜこうするかというと、標準準拠モードで動作している状態で、html 要素と body 要素双方に height: 100% が指定されていて、かつ overflow: auto が指定されていると、 position に relative か absolute が指定された要素が固定配置となります。

上記がそのまま今回のテクニックの肝なのですが、このままでは固定配置したくないものに対して position: absolute も position: relative も使えなくなってしまいます。
レイアウトによっては問題ないかもしれませんが、大体の場合においてどちらかひとつは必ず使いますよね。
ですが、このままでは本来の意味での position: relative や position: absolute が使えません。

想定していない要素の固定配置を防ぐ

そこで、div#coverが必要になってくるわけです。
まず、html と body 要素に overflow: auto の代わりに、横方向に関してはスクロールバーを内容に応じて出現するようにしつつ、縦方向のスクロールを消します。

さらに div#cover 要素にoverflow: autoを指定することで、縦方向のスクロールを div#cover で代用します。
加えて、position: relativeを追加することによって、 div#cover 自体も固定配置されたことになりますが、コンテンツ全体をくくっているため縦に長くなったコンテンツの場合は、これに指定されたoverflow: autoが働き、スクロールが維持される、というわけです。

さらに position: relative になっているため、この中で使われた position: absolute の指定も、本来の意図通りに反映される、というわけです。

最後に、この div#cover 外に置かれた position: relative(absolute) が指定された要素は固定配置されるので、まるでposition: fixedを指定したのと同じ動きをする、というわけです。

合わせて読むと役に立つかもなエントリー

この記事のカテゴリー一覧を見る⇒CSSテクニック

  • Hatenaブックマークに追加 Hatenaブックマーク数
  • livedoorクリップへ追加 livedoorクリップ数
  • Buzzurlにブックマーク Buzzurlブックマーク数
  • POOKMARK Airlinesへ追加
  • del.icio.usに追加

トラックバックURL

http://css-eblog.com/cgi-bin/mt/mt-tb.cgi/129

コメント

1 - gingami さん

はじめまして。
ちょうどこの動きを使いたくてとても参考・勉強になりました!
ただしカスタマイズでつまずいています・・・。

y軸は縦スクロールバーの動きと同じ(現状のまま)でいいのですが、
x軸はコンテンツ(幅900px 中央揃え)の右下に来るように固定したいのですが、
その位置にもってくることはできたのですが、
ie6でウィンドウのスクロールバーがウィンドウ内の900pxの縁にあらわれています。。。

また、スクロールしているうちに、突然したにいくと
bottom: 40px;
right: 40px;
が無効になるバグが発生しています。
説明がたりないですが、長くなりますので、説明はここまでで。。。

アドバイスできましたらよろしくお願いします。

2009年8月13日 18:57

2 - えど Author Profile Pageさん

>>1 - gingami さん
コメントありがとうございます。
ちょっと状況が分かりづらいのですが、
推測してみると、もしかして #cover に対して
width: 900px を設定していませんか?

このテクニックは、#cover を通常の body 要素の "代わり" として
使っています。
そのため、#cover はそのままで、さらにその内側に
#wrap などの要素を追加して、それに幅を持たせてみてください。

できれば、サンプルなどの URL を教えてもらえると
適切に回答できると思います。

バグに関してはちょっと実際にその現象が起きているものを見ないと分かりません;

2009年8月13日 19:17

3 - gingami さん

さっそくのアドバイスありがとうございます!

バグはこちらの記述ミスでした。解決しました。
失礼しました^^;

幅固定についてですが、coverの外側のタグに with:900pxいれてました。
ご指示のとおりcoverの子にwrapをつくり、
以下のcssを修正・追加したところmac safariで希望通りの動作を確認しましたが、
ie6だとスクロールと一緒に動いてくれなくなっちゃいました。。。
以下のcssをみていただけますか?

変更:
#fixedItem{
width:350px;
position: fixed !important;
position: absolute;
bottom: 80px;
padding: 10px;
padding-left:590px;}

追加:
#wrap{width:900px; margin:auto; position:relative;}


すいませんが、すぐにサンプルページをアップできません。
お時間ください。

2009年8月13日 19:55

4 - えど Author Profile Pageさん

>>3 - gingami さん
バグは記述ミスだったみたいでちょっと安心しました・・w

スクロールと一緒に動いてくれない、というのは
どこの部分でしょうか?
#wrap が、ということですか?

こちらでテストしたところ、
特に問題なく動いているようです。
やはり実際に問題が起きているものをアップしてもらわないと
これ以上の調査は難しいです;

2009年8月13日 21:30

5 - gingami さん

テストアップしました。
http://www.depth-vision.com/test.html

お手数おかけして申し訳ないですが、たすかります^^;

2009年8月14日 12:51

6 - えど Author Profile Pageさん

>>5 - gingami さん
確認しました。
えぇと、内容としては固定配置したいものが、
IE6 では固定配置されなくなった、ということでしょうか?

そうであれば、固定配置用のボックスが
#cover 内に入っているためです。

スクロール操作を、#cover が代替して行っていて、
その外に置かれたものが固定配置される、という仕組みのためです。

なので、固定配置したいものを
#cover の外に置いてみてください。

2009年8月14日 13:49

7 - gingami さん

coverの外側においたら固定配置になりましたが、
固定配置したい黒枠は、背景グレーエリアの右下につねにくるようにしたいので

で黒枠をくくったらie6ではスクロールバーがでなくなりました。。。
またみていただけますでしょうか?

http://www.depth-vision.com/test2.html

2009年8月14日 16:20

8 - えど Author Profile Pageさん

>>7 - gingami さん
どうやら #cover と指定されているのに、
cover が class になっているようです。

それから、area_cart の親の div は必要ですか?
これが悪さをしているようなので、
それを消してから、area_cart を
#cover の下に配置したら黒枠が固定配置されました。


かなり色々指定されているみたいですが、
まずはこれで動く、というところから
徐々に要素を足していくように作ると、
なにを追加したら動かなくなった、
というのが分かりやすいのでオススメです。

2009年8月14日 16:43

9 - gingami さん

classをidに直したら問題なくうごきました。
初歩的なミスですいませんでした。。。

area_cart の親の div は必要です。
グレーの背景の右側と黒枠の右側がそろったじょうたいで上下に動くようにしたかったので。
ただし、

にして問題なくうごきました。height等はいれませんでした。

なにでおかしくなったかを検証するやりかたが確かにいいですね。
今後気をつけます。

ありがとうございました。

2009年8月14日 17:46

10 - えど Author Profile Pageさん

>>9 - gingami さん
問題が解決したようでよかったです。
ID と class って、なにげに修正していると間違えるんですよね・・。
あれ、なんで適用されないんだーってあわてるときがありますw

2009年8月14日 17:51

11 - gingami さん

お恥ずかしいかぎりです。。。
でもとにかくie6でのposition:fixed対応はとても勉強になりました。
(まだよくわかってない部分もありますが・・・)
またのぞかせていただきます^^

2009年8月14日 18:09

12 - junpei kamiya さん

ありがとうござます。
とても参考になりました。

説明のしかたがわかりやすく、具体的に解説されていたので、
初心者の僕でも、すぐに理解できてよかったです。

サイトを公開しながら制作していきたかったので、
さっそく活用させていただきました。
http://maruka-fudousan.com/

今後もこのサイトを利用させていただきます。

2010年1月27日 12:33

13 - えど Author Profile Pageさん

>>12 - junpei kamiya さん
コメントありがとうございます!
お役に立てたようでよかったです(*'-')

ちょっと回りくどいやり方になってしまいますが、
IE6 対策がいらなくなるまでの辛抱ですね(;´д`)

2010年1月27日 12:45

コメントを投稿





承認されるまでコメントは表示されません。しばらくお待まちください。