2006年02月16日(木) コメント:0 トラックバック:2
floatを使った段組では、各カラムのwidthの合計がコンテナの幅を超えないことが「カラム落ち」しないことの条件だと思われがちですが、 仕様にはそのような規定はありません。重要なのはマージン辺(外辺)です。
floatによる段組は「ボックスの回りこみ」なんていう曖昧な表現では説明できません。 浮動体の振る舞いを支配する厳密な規則を、 2カラムレイアウトにおける連続するふたつの左フロートに適用して考えると、
<div id="container">
<div id="main">
1番目の左フロート
</div>
<div id="sub">
2番目の左フロート
</div>
</div>
- 2番目の左フロートの外左辺(左マージン辺)は、1番目の左フロートの外右辺より右側になければならない
- 2番目の左フロートの外右辺は、コンテナの右辺より右側にあってはならない
- これらの条件が守られている限り、ふたつの左フロートは可能な限り左寄せで横に並ぶ
- そうでないなら、2番目のフロートは1番目のフロートの外下辺より下に配置され(カラム落ち)、可能な限り左に寄せられる
カラム落ちするかどうかは、カラムの幅ではなくマージン辺に依存するということです。 各カラムのwidthの合計がコンテナの幅を超えていても、マージン辺について上記の規則を守っていればカラム落ちしないわけです。
これを理解していればネガティブマージン(負のマージン)によるレイアウト法の仕組みがわかるようになります。 たとえば、ネガティブマージンを使えば、「サイドバーの幅はpx単位で固定、記事領域は可変」というレイアウトが可能です。
#main {
width: 100%;
float: left;
}
#sub {
width:200px;
float: left;
}
フロートさせるには幅指定が必要なのでwidthを指定します。#mainの幅がコンテナの100%なので、これらのボックスは横に並びません。 #mainの外右辺がコンテナの右辺にぴったり合った状態のため、「#subの外左辺が#mainの外右辺より右側かつ#subの外右辺がコンテナの右辺の左側」という条件を満たせないのです。
ネガティブマージンを使えば幅はこのままで上記の条件を満たせます。 条件を整理すると、この例の場合、左から順に以下のようになっていればカラム落ちしません(#subの外左辺と外右辺は入れ替え可)。
- #mainの外右辺
- #subの外左辺
- #subの外右辺
- コンテナの右辺
たとえば#main { margin-right:-200px;}とすれば#mainの外右辺は#mainの右辺より内側に200pxの位置になります。
すると#subの外左辺は#mainの外右辺より右側で可能な限り左寄せ、すなわち#mainの右辺の内側200pxの位置になり、そうなれば#subの外右辺はコンテナの右辺より左側(というか一致)になるので、カラム落ちしないための条件を満たします。
#sub { margin-left:-200px;}としても同様です。ただし、どちらも#mainと#subの内容は重なってしまいます。
そこで、#mainの子要素でmargin-right:200pxを指定します。
#sub { margin-right:-200px;}の場合も同じ理屈でボックスは横に並びます。この場合は#subの内容がコンテナをはみ出すので横スクロールが生じる場合があります
(内容はコンテナをはみ出しているが、外右辺ははみ出していない)。
そこで、#container { padding-right:200px;}を加えます。
#subの内容がコンテナの右辺をはみ出しても、はみ出した先が#containerのパディング領域なら横スクロールは生じません。
このように、サイドバー幅固定、記事領域幅可変レイアウトには(理屈の上では)いくつか実現方法があるのですが、 方法によってはIEでうまくいかないので、結局試行錯誤するはめにはなります。
コメント(0件)