KOJIKA17

IE8から始めるテーブルレイアウト と IE10からのFlexible Box

テーブルレイアウトと聞くと<table>タグを使い、入れ子で<tr>, <td>タグのオンパレードを連想する人も多いと思いますが、今回の内容はCSSの display: table; を使用したテーブルレイアウトの話です。

display: table; はCSS2.0からある仕様です。
要素をCSSでテーブルのようにあしらうことができるため、多くの利点があります。

display: table;

display: table;はIE8以降のtable要素に、デフォルトスタイルシートで定義されているものです。
IE8からサポートされているのでIE7以下を切り捨てれば、今からでも使うことができます。
display: table;以外にも多くの値が存在し、tableを形作る要素に振り分けられています。

以下は、tableに振り分けられているCSSの例です。

table {
  display: table;
}

caption {
  display: table-caption;
}
col {
  display: table-column;
}

colgroup {
  display: table-column-group;
}
thead {
  display: table-header-group;
}
tbody {
   display: table-row-group;
}
tfoot {
  display: table-footer-group;
}

tr {
  display: table-row;
}
th, td {
  display: table-cell;
}

これらのCSSを、任意の要素に割り当てることによって、table要素に似たレイアウトにすることが可能です。

CSSによるテーブルレイアウト

実際にulなどの要素を、テーブルのようにする例です。

1列横並び

CSSで1列の横並びを再現する場合の例です。
tableとtable-cellの2つで行います。

<style>
ul {
  display: table;
}

li {
  display: table-cell;
  width: 80px;
  border: 1px solid #000;
}
</style>

<ul>
  <li>demo<br>demo<br>demo</li>
  <li>demo</li>
  <li>demo</li>
  <li>demo</li>
</ul>


1列横並びのデモ

テーブルのようにあしらうことができるので、子の要素の高さが変わっても、他の子も要素も同じ高さに保ってくれます。

上の例は、display: tableとtable-cellだけで、tr要素にあたる display: table-row;を使用していません。
display: tableとtable-cellだけでは、table要素の直下にtd要素を入れているのと同じことになりますが、ブラウザはtr要素に相当するものを追加してレンダリングしてくれます。
もしバグに遭遇した場合は、display: table;をdisplay: table-row;に変えてみて下さい。

画面中央配置

display: table;を使用することで画面中央配置が簡単にできます。

<style>
html {
  display: table;
  width: 100%;
  height: 100%;
}
body {
  display: table-cell;
  height: 100%;
  text-align: center;
  vertical-align: middle;
}
</style>

<body>
  <h1>画面中央配置</h1>
  <p>デモキャプション</p>
</body>


中央配置のデモ

JSなどを使用しなければ、ややこしい中央配置も、display: table;を使用すれば、CSSだけで簡単に中央配置ができます。

HTMLの順序を入れ替える

display: table;を使用することによって、HTMLの順序を無視したレイアウトにすることができます。

サンプルではMedia queriesを使用し、ブレークポイント設定しました。
PCで見られている方は、デモのページでウインドウサイズを広げたり、縮めたりしてみて下さい。
レイアウトの変化が確認できます。


display: table;でレイアウトが変わるデモ

ブレークポイントは320pxから800pxの間で、160pxごとに設定しています。

  • 2カラム 800px
  • 2カラム(headerとfooterを入れ替え) 640px
  • 1カラム(navと#mainを入れ替え) 480px
  • 1カラム(#contents, footer, headerの順で入れ替え) 320px

display: table;を使用することによって、table要素でいう、theadやtbody, tfootのように、内容の上下を入れ替えることが可能です。
以前ではtable以外では難しかった、HTMLの上下の並びをCSSのみで変更することができます。

なお今回のデモでは、変化がわかりやすいようにMediaQueriesを使用しました。
レスポンシブWebデザインで、この方法をとる場合は、本当に適切か考えてから使用して下さい。

CSS3のFlexboxについて

CSS3にも、display: table;に似たプロパティが存在します。
、勧告候補まで上がっているCSS Flexible Box Layout Moduleです。

display: table;よりも柔軟性の高いレイアウトが可能になる仕様です。
横並びはもちろん、tableではできないセル(ボックス)の均等配置、jQuery Masonryに似たレイアウトも可能です。

Flexboxは、FireFoxとwebkit系のブラウザでは、何年も前から実装されており、Opera12.1、IE10もFlexboxを対応しています。
PC、モバイルともにFlexboxが使用できる環境になってきていますが、Flexboxはたびたび仕様変更を繰り返しているおかげで、CSS3のGradientsと同じくらいカオスかもしれません。

変更が多いので、Flexboxのプロパティを一部紹介します。

古い Flexible Box 新しい Flexible Box ちょっと新しい Flexible Box さらに新しい Flexible Box
(勧告候補)
display:box; display: flexbox | inline-flexbox - display: flex | inline-flex
box-align flex-align - align-items
box-ordinal-group
初期値: 1
flex-order
初期値: 1
flex-order
初期値: 0
order
(さらに名前が変更される可能性がある)
初期値:0
box-pack: start | end flex-pack: start | end - justify-content: flex-start | flex-end

足並みが揃っていればいいのですが、対応状況はバラバラ。

  • 古くから対応しているFireFoxはflex実装のプレフィックスも外れて、手前まで来ているようですがデフォルト状態では使用できず、display: -moz-box;が基本。
  • Webkitは、対応がよく、古いFlexible Box、ちょっと新しいFlexible Box、さらに新しいFlexible Boxの対応がされています。
  • IE10に関しては、2012年3月22日版の「Flexbox」草案に基づいている(新しい Flexible Box)、と公式に書かれていますが、flex-orderの初期値が0のため、ちょっと新しいFlexible Boxが実装。
  • Opera12.1は、さらに新しいFlexible Boxがprefixなしで対応されています。

上記の内容から、Flexboxのプロパティを2つ設定してみます。

#flex {
  display: -moz-box;
  display: -webkit-box;
    /* webkitは、どのバージョンのFlexboxも使えますが、モバイルの後方互換を考えて、display: box; */
  display: -ms-flexbox;
  display: flex;

  -moz-box-pack: end;
  -webkit-box-pack: end;
  -ms-flex-pack: end;
  justify-content: flex-end;
}

プロパティ名が変わりすぎてカオスなのは、もちろんですがIE9まで使用できないので使う場所が限定されます。
機能は足りないですが、Flexboxのようなことがやりたい時は、display: table;を試してみると良いかもしれません。