テーブルレイアウトでよこ並び

displayプロパティのtable
とtable-cell
という値を使えば、HTMLの要素の<table>
や<td>
でマークアップしたのと同じようにレイアウトすることができます。そんなテーブルレイアウトを利用して、よこ並びしてゆきます!
テーブルは万能
テーブルレイアウトを利用するには、displayプロパティのtable
とtable-cell
という2種類の値を使います。
ul要素にdisplay: table
と指定し、li要素にdisplay: table-cell
と指定すれば、ul/li要素がtable/td要素さながらにレイアウトされます。
.nav_list {
display: table;
}
.nav_list li {
display: table-cell;
}
中央配置と、横幅いっぱい
ナビゲーション自体に、marginプロパティで左右にauto
と指定すれば中央に配置できるし、横幅100%
と指定すれば親要素いっぱいに広がる。しかもリンクボタンの横幅は、その要素の内容に合わせていい具合に伸縮してくれます:D。
.nav_list {
margin-inline: auto;
}
.nav_list {
width: 100%;
}
リンクボタンの幅を揃える
リンクボタンの数が5つと分かっているなら、li要素の横幅を20%
と指定すれば等分できます。
さらにtable要素ならでは、リンクボタンの数が変動するような場面でも、ul要素に横幅を指定しつつ、table-layoutプロパティにfixed
という値を指定すれば、li要素の幅が等分割になるように調整されます。
けどやっぱりフロートの時と同じく、ボタンの高さは、文字数によってマチマチになっちゃいますね…:(。
.nav_list li {
width: 20%;
}
20%
で等分.nav_list {
width: 100%;
table-layout: fixed;
}
td要素(=table-cell
を指定したli要素)はvertical-alignプロパティで、横に並ぶ要素の縦方向の位置を制御することもできるから、下のサンプルみたくvertical-align: middle
を指定すれば、リンクボタンを上下中央に揃えることができます。結局、凸凹で不格好だけど:(。
.nav_list li {
display: table-cell;
vertical-align: middle;
}
行数が違ってもボタンのサイズを揃える
li要素の高さは揃っているのだから、あとはa要素をli要素の高さまで引き伸ばせばよいわけです。
ということで、a要素の上下パディングを多めに指定してリンクエリアを広げたうえ、上下ネガティブマージンでパディングで広げた分を元に戻す、ということをします。
ここでは、もともと1em
あった上下のpaddingプロパティの値を5em
に広げ、marginプロパティでは上下に-4em
を指定しています。
このままだとa要素が余計に広がったままなので、li要素にoverflow: hidden
を指定することで、li要素からはみ出した部分を非表示にします。

.nav_list li {
display: table-cell;
overflow: hidden;
vertical-align: middle;
}
.nav_list a {
margin-block: -4em;
padding-block: 5em;
}
パディングによってa要素とli要素の領域が広がるけれど、ネガティブマージンではa要素の位置とli要素の領域だけが元に戻る、というトコがポイントです。
ボタンの大きさが揃いました:D!
レスポンシブにする
今のままだとビューポート幅が狭い時、いくらなんでもリンクボタンが縦に長すぎなので、レスポンシブにデザインを調整する必要があります。とはいえ、こういったナビゲーションは、スマホで表示する際には、だいたいたて並びにすることが多いです。
下のサンプルでは、画面の横幅が767px以下の時には、ul要素もli要素もdisplay: block
にして、たて並びになるようにしてます。それから、よこ並びの時には左側に指定していた1pxのパディングは、上側に指定するよう変更します。
あと、ボタンの高さを揃えるためにa要素に指定していた、ネガティブマージンや余計なパディングも必要なくなるので、元通りにしておきます。
@media screen and (max-width: 767px) {
.nav_list,
.nav_list li {
display: block;
width: auto;
}
.nav_list li:nth-child(n+2) {
padding: 1px 0 0;
}
.nav_list a {
margin: 0;
padding: 1em;
}
}
要領よく書き直す
よこ並びにするのは768px以上の時だけなので、テーブルレイアウトするためのスタイルはみんな、メディアクエリの(min-width: 768px)
の中にまとめちゃえばいいですね。さすれば、(max-width: 767px)
で元通りに指定し直す必要もないです!
@media screen and (min-width: 768px) {
.nav_list {
display: table;
table-layout: fixed;
width: 100%;
}
.nav_list li {
display: table-cell;
overflow: hidden;
vertical-align: middle;
}
.nav_list li:nth-child(n+2) {
padding-left: 1px;
}
.nav_list a {
margin-block: -4em;
padding-block: 5em;
}
}
@media screen and (max-width: 767px) {
.nav_list li:nth-child(n+2) {
padding-top: 1px;
}
}
テーブルで商品一覧
テーブルレイアウトするには、displayプロパティで、ul要素にtable
、li要素にtable-cell
を指定するのでした。商品一覧は商品の横幅が均等なので、table-layout: fixed
を適用して、li要素の幅が均等になるようにします。
.menu_list {
display: table;
table-layout: fixed;
width: 100%;
max-width: 1024px;
margin: 0 auto;
}
.menu_list li {
display: table-cell;
padding: 16px 24px;
}
テーブルなので改行できせん…XO!
テーブルセルが折り返さないのは仕方のないことなので、ここはHTMLの構造を変更するしかないです。下のサンプルでは、ul要素をふたつに分けてみました。
とはいえ、幅が狭い時には、2列になったり1列になったり、とても対応しきれないー…X(。
テーブルレイアウトは、商品一覧みたいな多段のよこ並びレイアウトには向いてない、ということですね…。

インライン・ブロックでよこ並び