2007年10月22日(月) コメント:0 トラックバック:0
floatとpositionの使い分けと類似の問題があったので紹介。
以下のHTMLでヘッダ、本文を右に寄せ、それらの左側にサイドバーを配置する。ただしサイドバーはページの一番上からの配置にしたい。
<div id="top"><h1>ヘッダ</h1></div>
<div id="main"><div class="content">本文</div></div>
<div id="sidebar"><div class="content">サイドバー</div></div>
<div id="footer"><p>フッタ</p></div>
- IE の float 処理について ◁ The Trap of Web Design
-
この、フロートブロックふたつ続きで、その後にフロート無しのブロックがある状況。 最後のフロート無しブロックの #sidebar をページの一番上からの配置にするには、どうする? ってことなんですが、Safari、Firefox、Opera ではどうするも何もそうなってるわけなので、IE(7・6-)でも同じくしたいんです。
#sidebarをページの一番上からの配置にするためには#sidebarにfloatを指定できません。
CSSの仕様に「フロートの上マージン辺はソース上で先に現れるブロック要素やフロートの上マージン辺より上に配置されない」という規則があります。
ヘッダの高さがわかっているならネガティブマージンやposition:relativeでどうにかできますが、ここではヘッダの高さは未指定です。
そこで、#sidebarはフロート無しで、ヘッダ(#top)と本文(#main)をフロートさせるわけですが、IE(7・6-)では何故かうまくいかない、という問題。
結論から言えば、#mainにclearを指定すればIE6でもうまくいきました(IE7は不明)。
この例では#sidebarの幅が本文のそれよりも狭いため本来ならclearは必須ではありませんが、本文を幅50%以下でつくる場合にはclearは必要です。
さて、後半に「#sidebarの幅を固定したもので同様のことができるか」という問題がありますが、単純に#sidebarに幅を指定するとIE6で例の3pxが発生します
(フロートに後続するボックスの幅がフロートに合わせて短縮される(5.x/6.0))。
オリジナルの出題では「#top と #main をグループ化」したものでお試しください
とありますが、グループ化せずとも実現できます。
やはりネガティブマージンを使うことになります。
順を追って解説します。
-
#top { width: 100%; float: right; } #main { width: 100%; clear: right; float: right; } #sidebar { width:200px; }#topと#mainを右にフロートさせます。 #sidebarはページの最上部から表示したいのでフロートさせません(理由は前述のとおり)。 今回#sidebarは幅固定なのでwidthを指定します。
フロートの幅が100%なのでこのままでは横に並びません。そこでネガティブマージンの出番です。
-
#top { width: 100%; float : right; margin-left: -203px; } #main { width: 100%; clear: right; float: right; margin-left: -203px; }負のmargin-leftにより#sidebarの右内辺が右フロートの左マージン辺よりも左になるようにすることで、#sidebarの内容を右フロートの左側に配置できます。 値が-200pxではなく-203pxなのは前述のIE6のバグ対策です。 (フロートとマージン辺を読んだ人は、 フロートにmargin-left: -203pxの代わりに、#sidebarにmargin-right: -203pxでもよいと思うかもしれませんが、 今回#sidebarはフロートではないので、その方法は適用できません。)
-
#top h1 { margin-left: 200px; } #main .content { margin-left: 200px; }最後に、#topと#mainの内側のボックスでmargin-left: 200pxを指定することで、これらのボックスの内容と#sidebarの内容が重ならないようにします。 ネガティブマージンを使ったレイアウトではよくやる方法です。
コメント(0件)