2カラム(メニューが先の場合)

最終更新 2006年3月6日

ページ内目次

いわゆる「ブログ」ではメニューを先に記述したやりかたはおすすめしませんが、本文の前にメニューがあってもいいわけです。

このページで紹介するサンプルは、すべてつぎの 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カラムとやり方は同じなので、詳しくはそちらを参照して下さい。 こちらはサイドバー部分を先に記述するので、左サイドバーならサイドバーを左フロート、右サイドバーならサイドバーを右フロートにします。

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

body {
 text-align:center;
}

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

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

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

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

サイドバーの左右入れ替えは、float と clear の値を right に変更します。

幅可変 2カラム

メインカラムを先に記述する場合とやり方は同じなので、詳しくはそちらを参照して下さい。 こちらはサイドバー部分を先に記述するので、左サイドバーならサイドバーを左フロート、右サイドバーならサイドバーを右フロートにします。

幅可変 2カラム 右サイドバー

body {
 text-align:center;
}

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

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

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

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

サイドバーの左右入れ替えは、float の値の right と left を入れ替えるだけです。

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

フロートとマージンを利用した方法です。 この方法はメニューを先に記述した場合にしかできません。 問題点もあります。

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

手順 1. センタリング

body {
 text-align:center;
}

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

幅 96% にしてセンタリングします。

詳しくは 幅可変 2カラムの説明を参照してください。

手順 2. ボックスB に幅とフロート

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

ボックスB は 幅を 200px で固定し、左にフロートさせます。 あとにつづく内容はボックスB の右側に回りこみます。

このままではボックスC がボックスB よりも長いときに、ボックスC の内容がボックスB の下にも流し込まれます(繰返しますが、これがフロートの「普通」の使い方です)。 この挙動は次のように考えます。

フロートは通常の流し込みに属していないため、ボックスC はボックスB が存在しないかのように配置されます。 ただし、ボックスC の行ボックス(文字列が入る部分)はボックスB に重ならないように幅が短縮されます(この場合、200pxだけ短くなる)。

手順 3. ボックスCに左マージン

#boxC {
 margin-left:200px;
}

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

ボックスC に左マージンをつけることで、ボックスC のブロックボックスがボックスBに重ならないようにします。 これで2段組レイアウトになりました。

ボックスB がボックスC より長くなった場合にもレイアウトが保持されるようにボックスD で clear しておきます。 clear したボックスは、そのボーダー上辺がフロートの外下辺より下にくるようになります。

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

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

body {
 text-align:center;
}

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

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

#boxC {
 margin-right:200px;
}

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

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

問題点

この方法の問題点は、メインカラムの中で clear をしてしまうと、そこでサイドバーのフロートが「解除」されてしまうことです。

clear したボックスは、そのボーダー上辺が、先行するフロートの外下辺より下にくるように、上マージンが増加します。 つまり、本文中で clear をした場合、そこからメニューの下の位置まで間が空いてしまうことになります。

メインカラム幅可変、サイドバー幅固定 2カラム(ネガティブマージン型)

方法1 の問題点を克服したやり方です。ただし相当やっかいです。

フロートと負のマージンを使って実現します。

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

手順 1. センタリング

body {
 text-align:center;
}

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

手順 2. 幅とフロート

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

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

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

サイドバーに幅 200px と左フロート、メインカラムに幅 100% と左フロート。 メインの幅を100% とするのがポイントです。フロートには幅を与えなければなりません。 ボックスD では clear しておきます。

ただしこのままでは横に並びません。

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

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

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

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

※このとき、ボックスB に負の右マージンではなく、ボックスC に負の左マージンを指定する方法では、IE でうまくいかないことがあります。

イメージ図1

手順 4. z-index

#boxB {
 width:200px;
 float:left;
 margin-right:-200px;
 position:relative;
 z-index:2;
}

#boxC {
 width:100%;
 float:left;
 position:relative;
 z-index:1;
}

z-index により、重なり合いの順序を指定します。 z-index は position の値が static(デフォルト)以外のボックスに対してのみ有効なので、それぞれのボックスに position:relative を指定します。 ボックスB を前面にするために、ボックスB の値を大きくします。

イメージ図1

Opera8.5ではボックスBの中の要素でz-indexを指定する必要があります。

#boxB>* {
 position:relative;
 z-index:2;
}

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

body {
 text-align:center;
}

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

#boxB {
 width:200px;
 float:right;
 position:relative;
 z-index:2;
}

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

#boxC {
 width:100%;
 float:right;
 margin-right:-200px;
 position:relative;
 z-index:1;
}

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

margin, float, clear の値の left と right を入れ替えます。 今度はボックスB ではなく、ボックスC に負のマージンを与えるほうがよさそうです。

参考資料