テーブルタグを使わずにテキストを上下中央揃えする方法

CSS HappyLifeさんがマルチレイアウトの上下中央揃えをする技を紹介していました。
ただしちょっと気になるのがCSSの「table-cell」を使っている点。
これは本末転倒な感じがするのは私だけでしょうか?

画像とかの横にあるテキストを上下中央に|CSS HappyLife

まず、縦方向をセンタリング(中央揃え)するには「vertical-align」を使用します。が、ここで問題なのは、この「vertical-align」が適用される要素は、「インライン要素」あるいは「テーブルのセル」であり、ブロック要素には適用されないという点です。

そこでブロック要素をCSSを使ってインライン要素あるいはテーブルのセルにする必要があります。上記に挙げた「table-cell」はテーブルセルを表すものです。

ここで少しおかしいと思ってしまいました。確かにtable-cellを使用すれば上下中央揃えできますが、これはtableタグを使っているのと概念的には同義だと思うのです。そもそもレイアウトにHTMLのテーブルタグを使うのはおかしいとさんざん議論しておきながら、表でもないのにレイアウトのためにテーブルセルを表すCSSのtable-cellを使うのは、やはり奇妙な気がします。表として扱うなら全然問題ないと思っていますが。うーん、考えすぎですかね?

今まで回りこみはインライン要素(あるいはfloat)を使ってきたので、この場合もインライン要素を使うのがこれまでの流れにあっているような気がします。

ブロック要素をインライン要素にする方法は、

  1. display:inline
  2. display:inline-block

のふたつが考えられます。

ただし、このあたりはきちんと検証していないのですが、IE6および7以外のブラウザは、display:inlineでは意図した表示にならないようです。display:inlineは指定したボックスの中にはインライン要素しか記述できないためだと考えられます。

一方の、display:inline-blockは、行内に配置されるブロックレベルボックスを生成します。つまり、display:inline-blockを指定したボックスの中にはブロック要素も記述できるということです。しかし、これはCSS3から適用されるプロパティで、うそです。CSS2.1で勧告されてました><現在、Opera9とSafariしか有効ではないとのこと。

さらに問題があって、Operaでは、インライン要素を横並びにする場合、タグを改行してしまうと改行をスペースと判断してしまい、半角文字分のスペースが空いてしまいます。 これを回避する方法としては、タグを改行せずに一行で書くということです。あるいは 以下のような書き方をして回避するしかないようです。

<div>
コンテンツ
</div><!--
--><div >
コンテンツ
</div>

あと、FirefoxとNetscapeなのですが、「display:-moz-inline-box;」という便利なGeckoエンジンの独自のプロパティがあるので、これが「display:inline-block」の代わりとして使うことができます。

IEでなぜ、「display:inline」でブロック要素を内包できるのかという疑問は、ヨモツネットさんのblogを参考にしてみてください。(要は、インライン要素でもhasLayoutがtrueだったらinline-blockになるよってことらしいのですが。)

ヨモツネット[日記] » CSS で簡単に上下中央揃えを実現する

あと、もうひとつ問題があって、「display:inline-block」内のblock要素はきちんと幅を指定していないと、囲んである要素(例えばdivとか)の幅指定をしていてもはみ出して表示してしまいますので注意です。

以上のことをふまえまして、コンテンツ(内容物)を上下中央揃えする記述方法は以下のとおりです。

<div id="main">
<p>中身</p>
</div><!--
--><div id="sub">
<p>中身</p>
</div>
#main {
   display: inline-block;/* Opera Safari用 */
   display:-moz-inline-box;/* Firefox Netscape用 */
   vertical-align:middle;
   width: 100px;
}

#sub {
   display: inline-block;/* Opera Safari用 */
   display:-moz-inline-box;/* Firefox Netscape用 */
   vertical-align: middle;
   width: 100px;
}

/* IE 6 */
* html #main,
* html #sub{
   display:inline;
   zoom:1;
}

/* IE 7 */
*:first-child+html #main,
*:first-child+html #sub{
   display:inline;
   zoom:1;
}

p {
   width: 100px;
}

Operaのバグが解消され、IE8とFirefox3が出たら(IE8とFirefox3はdisplay:inline-blockに対応しているとのことです。)、もう少しましな書き方になるんでしょうね。

以上のように考察してみると、「table-cell」のほうがバグがなくて使いやすいなと思いました><

疑問

なんでIEでは「table-cell」は意図した形にならないんだろう?調べているのですがよくわかりません><

広がる妄想

もうこうなったらマルチカラムプロパティがあればいいんじゃない?

例えば、「multicolumn:left;」みたいな書き方をして、値によって回り込み位置を設定する。例えば、leftだったら左に回りこみ、rightだったら右に回りこみ、clearだったら回り込み解除とか。で、multicolumnは同時にdisplayも指定できてvertical-alignも有効とかとかwww

その他の参考サイト

ruzee.com - Steffen Rusitschka » Blog Archive » Align List Items Horizontally with CSS …

スタイルシートをめぐる冒険: inline-blockの奇妙な世界

ウノウラボ Unoh Labs: inline-blockでマルチカラムレイアウト

display: table-cell を使ったマルチカラムレイアウト - IT戦記

Equal height boxes with CSS | 456 Berea Street

投稿日:2008年3月19日 | 編集

トラックバック歓迎です。以下URLにて登録をお願いいたします。

このエントリーのトラックバックURL:

↓↓↓トラックバックしてくださった方々↓↓↓
※トラックバックされても管理人がスパムと判断したものは公開されません。

top

ホームページ作成に役立つコーナー