inline-blockを使ってのマルチカラムレイアウト(段組み)

IE8、FF3、Safari、Opera、Chromeで正式にサポートされているdisplayプロパティの値inline-blockを使ってマルチカラムレイアウトを実装するテストをしてみました。

View Demo

通常2段組み、3段組みなどのレイアウトを組む場合、floatプロパティを使って左右にふったりすると思いますが、今回はfloatを使わずに2段組のレイアウトを組んでみます。HTMLのソースコードは以下の通り

HTML Code

<div id="container">
	<div id="header">
		<h1>header</h1>
	</div>
	<div id="primary">
		<div class="section">
			<p>文章</p>
			<p>文章</p>
		</div>
		<div class="section">
			<p>文章</p>
			<p>文章</p>
		</div>
	<!-- // end #primary --></div><!--
	--><div id="secondary">
		<div class="section">
			<p>文章</p>
			<p>文章</p>
		</div>
		<div class="section">
			<p>文章</p>
			<p>文章</p>
		</div>
	<!-- // end #secondary --></div>
	<div id="footer">
		<address>
		Copyright
		</address>
	<!-- // end #footer --></div>
<!-- // end #container --></div>

inline-blockを指定した要素同士は改行コードの影響を受けて微妙に隙間が出来てしまうのでコメントを挿入して改行コードを埋めています。

さて、inline-blockに対応していないブラウザにIE6、IE7、Firefox2があります。この中でIE6、IE7に関しては対応していない訳ではなく、いくつかの条件を満たせばinline-blockが有効になります。それには次のような条件があるようです。

  1. インライン要素(span要素やa要素など)には普通に使える
  2. ブロック要素にはdisplay: inlineの指定+zoom: 1;指定でhasLayoutをtrueにする
  3. 親要素にdisplay: inlineを指定し、子要素にdisplay: inline-blockを指定

Firefox2でレイアウトが崩れます

問題になったのはFirefox2です。Firefoxはdisplayプロパティに値-moz-inline-boxを指定することによりdisplay: inline-blockと同様なレンダリングになるとの事ですが、この値を指定した子要素が-moz-inline-boxを引き継ぐ?ようで思いっきりレイアウトが崩れます。これを解消するには-moz-inline-boxを指定した要素の直後に親要素の幅と同幅のwidthを指定し、displayプロパティに値blockを指定することで回避出来ます。

例えば次のようなdiv#primaryに-moz-inline-boxを指定した場合、div#primaryInnerの様なdivを追加すればその子要素は-moz-inline-boxの影響を受けなくなります。

CSS Code

div#primary {
	margin-left: 20px;
	width: 530px;
	display: -moz-inline-box;
	display: inline-block;
	vertical-align: top;
	/display: inline; /* for lte ie7 */
	/zoom: 1; /* for lte ie7 */
}
div#primaryInner {
	margin-bottom: 3em;
	width: 530px; /*親要素と同幅の値を指定*/
	display: block; /*displayの値をblockに*/
} /* for ff2 */

今回はFirefox2だけの為に不要なdivを追加しなければならないので、jQueryを使用してFirefox2のみに必要なdivを追加することにしてみました。

jQueryのソースコードは以下の通り

jQuery Code

$(function()
{
	if ($.browser.mozilla && $.browser.version <= "1.9")
	{
		$("div#primary").wrapInner("<div id='primaryInner'></div>");
		$("div#secondary").wrapInner("<div id='secondaryInner'></div>");
	}
});

これで-moz-inline-boxを指定したdiv#primary、div#secondaryの子要素にdiv#primaryInner、div#secondaryInnerがFirefox2のみに生成されます。

今回はレイアウト自体をinline-blockで組んでみましたが、実際の使い道としてはコンテンツ内に複数の連続したボックスを並べたりリストを使ったナビゲーションやインターフェイスなどに利用する事になると思います。その際もFirefox2でレイアウト崩れが起きたら子要素に同幅のdivを入れてdisplayをblockにすることを覚えておくと良いかもしれません。