2カラム(2段組)レイアウト

最終更新 2006年3月26日

ページ内目次

HTMLソース文書内では、メインカラム→サイドバーの順で記述した2カラムレイアウトです。 このページでは細かい注意事項を詳しく述べます(言い換えると、他のページでは割愛しています)。

このページで紹介するサンプルは、すべてつぎの HTML に対して CSS を適用させます。

HTML

<div id="container">

 <div id="boxA">
 A(ヘッダ)
 </div>

 <div id="boxB">
 B(メインカラム)
 </div>

 <div id="boxC">
 C(サイドバー)
 </div>

 <div id="boxD">
 D(フッタ)
 </div>

</div>

HTMLの構造はこのようになっているとします。実際に作るときには id 名をもっと適切なもの(title, header, content, main, sub, menu, nav, footer など)に変更してください。

幅固定 2カラム

ブログでよくある横幅固定、2カラムのレイアウトです。横幅は 700px として説明します。 ウインドウ幅が狭くなると横スクロールが出ますが、レイアウトは保持されます。

幅固定 2カラム 右サイドバー

手順 1. センタリング

#container {
 width:700px;
 margin-left:auto;
 margin-right:auto;
}

ブロックレベル要素である div 要素をセンタリングするには width とともに左右のマージンに auto を指定します。 左右のマージンが同じ値になるように自動調節され、結果としてセンタリグされます(10.3.3参照)。 ここでは左右カラムのコンテナブロックである #container に対して指定します。

WinIE5.5 以下や IE6 のQuirks モードでは マージンの auto に対応していません。 しかし IE には text-align:center でブロック要素をセンタリングしてしまうバグがあるため、これを利用すればこれらのブラウザでもブロック要素のセンタリングが可能です。

body {
 text-align:center;
}

#container {
 width:700px;
 margin-left:auto;
 margin-right:auto;
 text-align:left;
}

body 要素に対して text-align:center を指定すると、IE6 はその子要素のブロック要素である div#container をセンタリングします。 このままではブロック要素だけでなく中のテキストまでもセンタリングされてしまうので、#container に text-align:left を指定し、テキストは左寄せに戻します。

手順 2. 幅とフロートの指定

#boxB {
 width:500px;
 float:left;
}

#boxC {
 width:200px;
 float:left;
}

#boxD {
 width:100%;
 clear:left;
}

ボックス B と C に float を指定し、ふたつのボックスを横に並べます。ボックス D には clear を指定します。ボックスDの width:100% は IE6 のバグ対策です。

ボックス B と C の幅の合計はコンテナブロックの幅と同じにしています。 ボックス B、C には width を指定してあるため、これらに padding や border は指定しません。

サイドバーの左右入れ替え

body {
 text-align:center;
}

#container {
 width:700px;
 margin-left:auto;
 margin-right:auto;
 text-align:left;
}

#boxB {
 width:500px;
 float:right;
}

#boxC {
 width:200px;
 float:right;
}

#boxD {
 width:100%;
 clear:right;
}

float と clear の値を right に変更します。

メインカラムとサイドバーの間に 10px の余白をつける

#boxB {
 width:490px;
 float:right;
 margin-left:10px;
}

#boxC {
 width:200px;
 float:right;
}

#boxD {
 width:100%;
 clear:right;
}

ボックスB の幅 490px +右マージン10px +ボックスC の幅 200px でコンテナブロックの幅と同じになります。 右サイドバーの場合は float と clear の値を right に変更します。

フロートとマージンのバグに注意

float と margin に関して、IE6 にはやっかいなバグがあります。 左フロートしているボックスに対して左マージンを指定すると、指定値の倍のマージンが空いてしまいます (ただし、左フロートの前に、さらに左フロートがある場合は、後の左フロートに左マージンを指定しても倍にはならないようです)。 右フロートの場合も同様で、先に右フロートしたボックスの右マージンが指定値の倍になります。

よって、できるだけfloat:left を指定したボックスには margin-left を指定しない(0にする)、float:right を指定したボックスには margin-right を指定しない(0にする)ようにしましょう。

このバグは float を指定したボックスに display:inline を指定すると回避できるようです。 CSS2の仕様ではフロートしたボックスの display は強制的にブロックレベルな値に修正されるので display:inline を指定したことによる不具合はないと思われます。

幅可変 2カラム

ウインドウ幅によって全体の幅が変わります。 幅を % 単位で指定するため、px や em 単位のボーダーやパディング、マージンは「カラム落ち」の原因になります。 よって width とともにボーダーとパディングをつかない上に、マージンの単位も%を使用します。

幅可変 2カラム 右サイドバー(ダブルフロート型)

フロートを 2度使う方法です。

手順 1. センタリング 方法 1

body {
 text-align:center;
}

#container {
 width:96%;
 margin-left:auto;
 margin-right:auto;
 text-align:left;
}

コンテナブロックの幅を body 要素(ウインドウ幅)の96%にして、左右の余白を2%ずつにします (margin の auto と、text-align については幅固定の場合を参照)。

センタリング 方法 2(おすすめできない方法)
#container {
 margin-left:2%;
 margin-right:2%;
}

コンテナブロックの左右の余白を2%ずつにすれば、コンテナの幅は残りの96%になります。 Firefox ではセンタリング 1 の方法と同様の表示になりました。しかし IE6 の Quirks モードでは何故かうまくいかないようです(上記の方法でセンタリングしたサンプル)。

コンテナブロックには幅を指定するのが無難なようです。

手順 2. 幅とフロートの指定

#boxB {
 width:70%;
 float:left;
}

#boxC {
 width:29%;
 float:right;
}

#boxD {
 width:100%;
 clear:both;
}

メインカラムはコンテナの 70% の幅、サイドバーは 29% の幅、メインカラムとサイドバーの間に1%の隙間があるレイアウトです。

ここではボックスBが float:left でボックスCが float:right であることに注意してください。 したがってボックスDでの clear は both になります。(サイドバーの左右入れ替えには float の値の right と left を入れ替えます。)

何故これまでのように両方とも float:left でないのか、何故二つのボックスの合計が100%でないのかは これから説明します。簡単に言うと、こうしないと IE6 で段組が崩れるからです。

カラムの幅を合計100%にすると(おすすめできない方法)
#boxB {
 width:70%;
 float:left;
}

#boxC {
 width:30%;
 float:left;
}

#boxD {
 width:100%;
 clear:left;
}

この方法は一見うまくいったように見えます。しかし IE6 ではウインドウのサイズを変えていったときに(大きくしたときでさえ)、稀に「カラム落ち」が発生します。 ボックスCに対して float:right としても同じです(各カラムの幅合計100%の場合のサンプル)。

メインカラム+サイドバー+余白1%で合計100%(おすすめできない方法)
#boxB {
 width:70%;
 float:left;
 margin-right:1%;
}

#boxC {
 width:29%;
 float:left;
}

#boxD {
 width:100%;
 clear:left;
}

ボックスBが70%、ボックスBの右マージンが1%、ボックスCは29%で、合計100%です。 はじめに示した方法と同じように表示され、一見うまくいったように見えます。しかしこれもカラム落ちが発生するウインドウサイズが存在します。 ボックスCに対して float:right としても同様です(メインカラム+サイドバー+余白1%で合計100%の場合のサンプル)。

ウインドウサイズを変化させたとき、%値がpx値に変換される過程で端数が生じ、そのためにコンテナブロックの幅をこえてしまうものと考えられます。

したがって、ボックスBとボックスCの幅の合計が100%より小さくなるようにし、ボックスBは左フロート、ボックスCは右フロートにして、マージンは指定しないというはじめの方法が、崩れにくい幅可変 2カラムの実現方法ということになります。

両方とも左フロートにすると(カラムの幅は合計99%)
#boxB {
 width:70%;
 float:left;
}

#boxC {
 width:29%;
 float:left;
}

#boxD {
 width:100%;
 clear:left;
}

もちろん両方とも float:left にすることもできます。しかしカラムの合計が100%より小さいため、隙間が右端にできてしまいます(カラム幅合計99%、両方とも左フロートのサンプル)。 これはかっこ悪いと思いませんか。片方を左フロート、もう一方を右フロートにすれば隙間はカラムの間になるのです。

サイドバーの左右入れ替え(ダブルフロート型)

body {
 text-align:center;
}

#container {
 width:96%;
 margin-left:auto;
 margin-right:auto;
 text-align:left;
}

#boxB {
 width:70%;
 float:right;
}

#boxC {
 width:29%;
 float:left;
}

#boxD {
 width:100%;
 clear:both;
}

float の値の right と left を入れ替えるだけです。

幅可変 2カラム 右サイドバー(フロート+マージン型)

フロートとマージンを使った方法です。

body {
 text-align:center;
}

#container {
 width:96%;
 margin-left:auto;
 margin-right:auto;
 text-align:left;
}

#boxB {
 float:left;
 width:70%;
}

#boxC {
 margin-left:70%;
}

#boxD {
 width:100%;
 clear:left;
}

イメージ図1 イメージ図2

ボックスB に幅と左フロートを指定し、ボックスC にはフロートに重ならないように左マージンを与えます。 左右の入れ替えは、margin, clear, flaot の値の right と left を入れ替えるだけです。

ボックスC に width を指定すると IE6 のバグにひっかかるので注意しましょう。

メインカラム幅可変、サイドバー幅固定 2カラム

コンテナブロックとボックスB の幅は可変(%)で、ボックスC の幅は固定(px など)のレイアウトも、このままのHTML構造で可能ですが、相当やっかいです。

サイドバーを先に記述するか、position を使えばずいぶん簡単になりますが、前者の方法では HTML 自体に手を加えなければなりませんし、後者の方法ではサイドバーが長くなった場合にフッタと重なる可能性があります。

今回は HTML はそのままで、フロートとマイナスのマージン(ネガティブマージン)を利用して実現します。

メインカラム幅可変、右サイドバー幅固定 2カラム

手順 1. センタリング

body {
 text-align:center;
}

#container {
 width:96%;
 margin-left:auto;
 margin-right:auto;
 text-align:left;
}

手順 2. 幅とフロート

#boxB {
 width:100%;
 float:left;
}

#boxC {
 width:200px;
 float:left;
}

#boxD {
 width:100%;
 clear:left;
}

ボックスB に幅 100%、ボックスC に幅 200px を指定し、それぞれをフロートさせます。 ボックスB の幅 100% がポイントです(フロートには幅が必要)。 ボックスD で clear しておきます。ただしこのままでは横に並びません。

手順 3. ネガティブマージン

#boxB {
 width:100%;
 float:left;
 margin-right:-200px;
}

#boxB>* {
 margin-right:200px;
}

イメージ図

ボックスB にボックスC の幅と同じだけの負の右マージンを与え、ボックスB と C を重ねます。 さらに、ボックスB の子要素に 200px の正の右マージンを与え、子要素とボックスC が重ならないようにします (IE が子セレクタに対応していないため、実際には子孫セレクタでブロックレベル要素に対して指定するか、id や class を持つ div 要素をもうひとつ使うことになります)。

サイドバーの左右入れ替え

body {
 text-align:center;
}

#container {
 width:96%;
 margin-left:auto;
 margin-right:auto;
 text-align:left;
}

#boxB {
 width:100%;
 float:right;
 margin-left:-200px;
}

#boxB>* {
 margin-left:200px;
}

#boxC {
 width:200px;
 float:right;
}

#boxD {
 width:100%;
 clear:right;
}

margin, float, clear の値の right と left を入れ替えるだけです。

注意事項

段組レイアウトの際に気をつけるべきことを繰返します。

これらの制約は標準準拠しつつ、WinIE6 でも崩れないようにするためです。

参考資料