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

最終更新 2006年3月26日

ページ内目次

float を使った 3段組は HTML の構造がやや不明瞭になります。 すなわち、div 要素でのグループ化が内容に即さないものになりがちです。

position を使えば必要な div 要素の数は少なくなり、それなりに妥当なマークアップを保持できますが、 position でのレイアウトでは float でのそれと同様の表示結果を実現するのは難しくなります。

どちらにせよ、本来上から順に縦に書かれる HTML 文書を 3カラムレイアウトにするのには無理があるため、マークアップが多少汚くなっても仕方ないものと考えてください。

さて、3カラムということは性質の異なる 3つのブロックを用意することになります。 2カラムでは、「本文+ナビゲーションなど」の 2つでした。 今回は 3カラムなので、「本文+ナビゲーション+広告など」の 3つを想定します。

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

HTML

<div id="container">

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

 <div id="wrapper">

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

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

 </div>

 <div id="boxD">
 D(サイドバー2)
 </div>

 <div id="boxE">
 E(フッタ)
 </div>

</div>

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

幅固定 3カラム

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

幅固定 3カラム

手順 1. センタリング

body {
 text-align:center;
}

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

幅固定 2カラムのときと同様です。

手順 2. #wrapper とボックスD を横に並べる(右側にボックスD)

#wrapper {
 width:620px;
 float:left;
}

#boxD {
 width:180px;
 float:left;
}

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

ボックスD を右サイドにする場合、#wrapper を左にフロートさせます。ボックスE で clear をしておきます。width:100% は IE のバグ対策です。

ボックスD を左サイドにする場合は float と clear のleft を right にします。

手順 3. #wrapper 内のボックスB、Cを横に並べる

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

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

ボックスB を3段組の中央にするため、ボックスB を右フロートさせます。ボックスC も同様にフロートさせます。

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

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

body {
 text-align:center;
}

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

#wrapper {
 width:620px;
 float:right;
}

#boxD {
 width:180px;
 float:right;
}

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

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

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

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

各カラムの間に 10px の余白を設ける

body {
 text-align:center;
}

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

#wrapper {
 width:610px;
 float:left;
 margin-right:10px;
}

#boxD {
 width:180px;
 float:left;
}

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

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

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

左フロートには左マージンを指定しない、右フロートには右マージンを指定しないのが無難です。

サイドバーを左右入れ替えるには float と clear の値の right と left を入れ替えます。

幅可変 3カラム

幅を可変(%)にするため、マージン、パディング、ボーダーを px や em 単位で指定できません。

float で実現する幅可変の段組レイアウトにはいろいろとコツがいります。詳しくは幅可変 2カラムを参照してください。 3カラムの場合は幅の計算が多少やっかいです。

幅可変 3カラム 間に 1% の隙間

ここでは、左右のカラムは同じ幅、中央カラムはやや広めで、カラムの間に 1% の余白を残したレイアウトにします。ゆとりを残しておくことでカラム落ちを防ぎます。 HTMLの構造上、左右カラムの直接の親要素が異なるため、幅の計算が面倒ですが、最終的に左カラム 24%、中央カラム 50%、右カラム 24%、合計でコンテナブロックの 98% の幅になるようにします。

手順 1. センタリング

body {
 text-align:center;
}

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

幅可変 2カラムのときと同様です。

手順 2. #wrapper とボックスD を横に並べる(右側にボックスD)

#wrapper {
 width:75%;
 float:left;
}

#boxD {
 width:24%;
 float:right;
}

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

#wrapper が幅 75% で左フロート、ボックスD が幅 24% で右フロートであることに注意してください。 幅の合計は 100% にしていません。ボックスE での clear はもちろん both とします。

手順 3. #wrapper 内のボックスB、Cを横に並べる

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

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

ここでのポイントは幅の計算です。ボックスB と C は、コンテナ(#container)の幅の 75% である #wrapper 内のボックスです。 コンテナの幅を 100 とすると、#wrapper が 75、ボックスD が 24、その間の余白が 1 になっています。

ボックスC の幅は、ボックスD の幅と同じにするために、75*0.32=24より、32% とします。

ボックスB の幅は、ボックスB と C の間が 1 になるように決めます。幅 66.7% とすれば、75-75*0.667-24=0.975≒1になります。

ボックスB を右フロートで 3カラムの中央に、ボックスC を左フロートで左端にします。

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

body {
 text-align:center;
}

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

#wrapper {
 width:75%;
 float:right;
}

#boxD {
 width:24%;
 float:left;
}

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

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

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

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

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

サイドバーの幅は固定し、その残りをメイン部分に割り振るのは、この HTML ではかなりやっかいです。

サイドバー1→サイドバー2→メインカラムの順で記述するか、position を使えばわりと簡単ですが、前者の方法では文書構造が不適切ですし、後者の方法ではサイドバーが長くなった場合にフッターと重なる可能性があります。

ここでは、float とネガティブマージンを使った方法で実現します。

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

手順 1. センタリング

body {
 text-align:center;
}

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

手順 2. #wrapper とボックスD に幅とフロート

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

#boxD {
 width:180px;
 float:left;
}

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

#wrapper とボックスD を左にフロートさせます。フロートには幅を指定する必要があるので、固定幅のボックスD には 180px を指定します。 #wrapper には 100% とするのがポイントです。ボックスE では clear しておきます。

ただしこのままではボックスは横に並びません。

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

#wrapper {
 width:100%;
 float:left;
 margin-right:-180px;
}

#wrapper にボックスD の幅と同じだけの負の右マージンを指定することで、#wrapper とボックスD を重ねます。 ボックスD が前面に表示されます。

イメージ図

手順 4. #wrapper内のボックスB、Cでも同様に

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

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

#wrapper内のボックスB、Cでも同様に 幅、フロート、負のマージンを指定します。 今度はボックスB を3カラムの中央にするために、右フロートです。

イメージ図

ボックスB とボックスC はやはり重なり合っており、ボックスC が前面に表示されます。

手順 5. ボックスB の子要素に左右マージン

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

ボックスB の子要素に左右 180px ずつのマージンを設け、子要素がボックスC、D と重ならないようにします(IEが子セレクタに対応していないため、実際には子孫セレクタをブロックレベル要素に対して指定するか、id や class をもつ div 要素をもう1つ使うことになります)。

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

body {
 text-align:center;
}

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

#wrapper {
 width:100%;
 float:right;
 margin-left:-180px;
}

#boxD {
 width:180px;
 float:right;
}

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

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

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

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

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

参考資料