段組レイアウトのお約束:段組ボックスの底辺を揃える(揃っているように見せる)

使い古されたネタで申し訳ないのですが、自分が復習するという意味も含め、CSSで段組レイアウトをする際のお約束をまとめてみることにしました。まず第一回は「段組ボックスの底辺を揃える(揃っているように見せる)」です。

以下の画像のような見た目の段組を、実現することを目標とします。

目標とする段組レイアウト図

普通に考えると、float を使って横に並べたボックス各々に border を適用したくなります。が、このやり方ですと各ボックスの内容量が異なる場合、各々の高さが異なってしまい、ボックスの底辺が揃わなくなります。このように。

各段組ボックスの底辺が揃わないの図

そこで、border を使わずに目標の見た目を実現します。

以下に示す方法は、例として2カラムの段組を取り上げていますが、3カラム以上の段組でも同じように利用することができます。ただし、横幅固定デザインでのみ有効です。リキッドレイアウトやエラスティックレイアウトでは手法を変えないと利用できません。

まず以下のような画像を作り、スライスを切ります。

作成する画像と、それにスライスを切った図

緑色の部分がスライスと思ってください。段組中段の部分を実現するためのスライスと、段組底辺を実現するためのスライスです。わかりやすいように高さ10ピクセル程度のスライスにしていますが、実際は中段部分は高さ1ピクセル、底辺は線の太さと同じで大丈夫です。

で、次のようなソースを書きます。あくまで一例です。

XHTMLのコード

<div id="container">
<div class="section" id="columnAlpha">
<h2>コラムA</h2>
<p>サンプルテキストサンプルテキストサンプルテキスト...</p>
</div>
<div class="section" id="columnBeta">
<h2>コラムB</h2>
<p>サンプルテキストサンプルテキストサンプルテキスト...</p>
</div>
<p id="containerBtm">&nbsp;</p>
</div>

CSSのコード

div#container {background:url(中段部分の画像.gif) repeat-y;}
div#columnAlpha {
float: left;
width: 162px;
border-top: 2px solid #339;
margin-right: 10px;
}
div#columnBeta {
float: left;
width: 162px;
border-top: 2px solid #339;
}
p#containerBtm {
clear: both;
height: 2px;
background: url(底辺部分の画像.gif) no-repeat bottom;
font-size: 2px;
line-height: 2px;
}

段組しているボックスには上辺のみ border を指定し、親のコンテナボックスに対して段組中段部分の画像をY軸リピートで指定します。そして、段組ボックスの直後に、底辺となる p#containerBtm を挿入し clear:both と、底辺部分の画像を背景に指定します。height と font-size、line-height の指定は、このボックスを底辺画像の高さピッタリにするためのものです。

p#containerBtm にあたるものは、clear ができてかつ底辺画像が表示できれば、なんでもいいです。底辺画像は背景ではなくて、img 要素で埋め込んでも構いませんし。p#containerBtm 自体入れたくない方は、コンテナdivをもうひとつ追加して、そちらに底辺画像を背景で指定 & clearfix を使う、というやり方でもいいです。また、きちんと内容を持っているフッター的なボックスを持ってきてもいいでしょう。

以上のような方法で底辺を「揃っているように見せる」ことができます。(実際は揃ってないです)

JavaScriptを使って強引に揃えちゃったサイトを先日、はやしさんに教えていただきました。

オーケーズデリカ株式会社: お弁当

お弁当一覧のところです。なんとまあ・・・

なお、クロスブラウザな表示を実現する際に border は障害となる場合がありますので注意が必要です。この点は ADP: ピクセル単位で合わせるところではborderを使わない(IE7でも!) においてよくまとめられています。

段組ボックスでは上辺のみを表現し、親コンテナボックスで中段部分を表現するのがミソですね。この点を抑えて工夫すれば、リキッドレイアウトやエラスティックレイアウトにおいても実現する方法はありそうです。

エラスティックレイアウトを採用してみました

当サイトのレイアウトにはエラスティックレイアウトという手法を使いました。コンテナ要素の幅をem単位で指定しています。該当部分の記述は以下の通り。

div#container {
width: 90%;
max-width: 60em;
min-width: 46em;
margin: 0 auto;
}

コンテンツ全体を囲む div#container に対して max-width と min-width をem単位で指定しています。そうすることで、ブラウザで文字サイズを変更すると div#container の幅が変わるようになります。なお、 max-width/min-width プロパティに対応していないIE6以前などのブラウザでは単に width:90% になるだけです。

また、エラスティックレイアウトで2カラムを実現するためにネガティブマージンをレイアウトに使っています。ネガティブマージンというのは文字通り、マイナス値を指定した margin プロパティのこと。

div#main {
float: left;
width: 100%;
margin: 0 -16em 20px 0;
}
div#sidebar {
float: right;
width: 15em;
margin-bottom: 30px;
}

div#sidebar の幅が15emで、残りの領域は div#main という割り当てとなっています。div#sidebar の width:15em に対して div#main の右 margin:16em 。差分の1emは間のマージン。これだけだと、div#main の右端が div#sidebar に潜ってしまうため、div#main の中身のブロック要素に右 margin を設定します。

div.entry {
margin: 0 16em 30px 0;
}

これで完成。

なお、このレイアウトには以下のサイトを参考にさせていただきました。
2xup.org: 一行あたりの文字数を制限する elastic layout (エラステックレイアウト)
Alternative Design Project: デザインテンプレート1110とネガティブマージン