段組みのCSS。
テーブルレイアウトで2段組みレイアウト
続いて、displayプロパティの値table
とtable-cell
を利用して、レイアウトを作ってゆきたいと思います。
と言っても、floatプロパティを使ったレイアウトの項で、メディアクエリの細かいポイントは整理できたので、あとは、フロートしてたところを、テーブルレイアウトで置き換えてゆくだけ、なはずです!
ヘッダーとナビゲーション
ひとまず、フロートの時のメディアクエリはそのままに、フロートしていた要素をテーブルレイアウトに置き換えます。
nav要素とナビゲーションにdisplay: table
(テーブル)を指定して、サイトタイトルとナビゲーションボタンにはdisplay: table-cell
(テーブルセル)を指定します。
ナビゲーションは、415px以上の時にはtable
が適用されますが、768px以上の時にはtable-cell
に上書きされることになります。
@media print, (min-width: 415px) {
.nav-list {
display: table;
}
.nav-list li {
display: table-cell;
border-left: 1px solid #eee;
}
}
@media print, (min-width: 768px) {
header nav {
display: table;
line-height: 80px;
}
.site-title, .nav-list {
display: table-cell;
}
.nav-list a {
padding: 0 2em;
}
}
中央に寄っちゃいました:ω。テーブル要素は、特に横幅の指定がないと、その内容にぴったりなサイズになってしまうので、nav要素をヘッダー内いっぱいに広げるために、nav要素の横幅を100%
に指定します。
それから、767px以下の時にはナビゲーションが横幅いっぱいになるよう、ナビゲーションの横幅を100%
に指定。
@media print, (min-width: 768px) {
header nav {
display: table;
width: 100%;
line-height: 80px;
}
⋮
}
@media screen and (max-width: 767px) {
.nav-list {
width: 100%;
}
⋮
}
縦方向の位置が、今はbaseline
に揃っている状態なので、これを中央揃えにするため、table-cell
を指定している要素にvertical-alignプロパティでmiddle
を指定します。
@media print, (min-width: 768px) {
⋮
.site-title, .nav-list {
display: table-cell;
vertical-align: middle;
}
⋮
ナビゲーションがロゴ側へ寄っちゃってますね…。これはテーブルレイアウトが持つアルゴリズムによって、よしなに横幅が決められているため。ここでは、このアルゴリズムを利用して、サイトタイトルの横幅を若干大きめに指定することで、テーブル要素を内側から広げるようにしたいと思います(詳しくは後述)。
@media print, (min-width: 768px) {
⋮
.site-title {
width: 60%;
}
⋮
あと、767px以下の時ナビゲーションボタンが均等になるところは、せっかくテーブルレイアウトなのでtable-layoutプロパティの値をfixed
とすることで均等に割り付けるようにします。すると、li要素への横幅の指定も要らないので、414px以下で横幅を戻す指定も要らなくなりますね:D!
@media screen and (max-width: 767px) {
.nav-list {
width: 100%;
table-layout: fixed;
}
⋮
テーブルレイアウトのヘッダー完成ー。
メインコンテンツとサイドメニュー
続いて、コンテンツエリアをテーブルレイアウトで2段組みです。
さっそく、#contents要素にtable
、メインコンテンツとサイドメニューにtable-cell
を指定します。
ただし、前述の自動テーブルレイアウトアルゴリズムの所為で、テーブルセルに横幅を指定しても思い通りの横幅にはならないため、メインコンテンツには75%
、サイドメニューには25%
を指定して、メインコンテンツとサイドメニューの隙間は、それぞれの内側にパディングで、明示的にpx幅を指定して空けることにします。
@media print, (min-width: 768px) {
#contents {
display: table;
}
main, aside {
display: table-cell;
}
main {
width: 75%;
padding-right: 20px;
}
aside {
width: 25%;
padding-left: 20px;
}
}
メインビジュアルもいっしょくたに、テーブルセルはみなよこ並びになってしまうんですね…。
そこで、メインビジュアルだけ横幅いっぱいに配置するため、メインビジュアルにはdisplay: table-caption
を指定します。テーブルキャプションならテーブルの上部に鎮座してくれるはずです。
@media print, (min-width: 768px) {
#contents {
display: table;
}
.visual {
display: table-caption;
}
⋮
ただし、テーブルキャプションはテーブル要素に指定してるパディングは無視して鎮座してしまうので、テーブル要素(#contents要素)に指定している左右のパディングをもう一度、メインビジュアルにも指定してやります。
あとは、メインコンテンツとサイドメニューの縦方向の位置を上辺で揃えるために、table-cell
を指定した要素にvertical-align: top
を指定すれば、いっちょあがり。
@media print, (min-width: 768px) {
⋮
.visual {
display: table-caption;
padding: 0 16px;
}
main, aside {
display: table-cell;
vertical-align: top;
}
⋮
商品一覧と記事一覧
これらもひとまず、フロートしてた部分をテーブルレイアウトに書き換えてゆきます!
それぞれ、ul要素にはtable
、li要素にはtable-cell
を指定して、フロートの時と同じように、li要素の左側にパディングで隙間を空けて、ul要素のズレをネガティブマージンで戻します。
案の定、こんな感じになります。やっぱり、ひどく申し訳ない気持ちになりますね…。X(
.menu-list {
display: table;
margin-left: -24px;
}
.menu-list li {
display: table-cell;
width: 33.333333%;
padding-left: 24px;
vertical-align: top;
}
商品一覧みたく、複数行に渡る一覧はテーブルレイアウトには向いてないです(「よこ並びのCSS。」参照のこと)。
どうしてもテーブルレイアウトじゃなきゃいやだ、という場合には、水平にスクロールするコンテンツにしちゃう手があります。
テーブルセル(li要素)には、横幅を指定しても、親要素の横幅に合わせて調整されちゃうので、一定サイズより小さくならないように、最小幅を指定しておくことにします。
ul要素には、ちょっと横着して、display: table
を指定しません。ブロック要素のままにしておくことで、明示的に横幅を指定してoverflow: auto
を指定した時に、横スクロールバーが表示されるようになります。
.menu-list {
overflow: auto;
margin-left: -24px;
}
.menu-list li {
display: table-cell;
min-width: 200px;
padding-left: 24px;
vertical-align: top;
}
同じように、サイドメニューの記事一覧とバナー一覧も、スクロールバーが出るように指定してます。どうせスクロールするやつなので、li要素の横幅は固定にしちゃって良いかもしれません。
一覧をスクロールすると、左側の見切れる位置が、セクションエリアからはみ出しちゃってますね…。ul要素を左にズラすと、見切れる位置ごとズレちゃうので、ul要素にネガティブマージンは指定しない方が良さそうですね…。代わりに、li要素のパディングは、最初のli要素以外に指定することにします。
.menu-list {
overflow: auto;
}
.menu-list li {
display: table-cell;
min-width: 200px;
vertical-align: top;
}
.menu-list li:not(:first-child) {
padding-left: 24px;
}
最初の画像だけ大きくなっちゃいましたね。content-boxプロパティでborder-box
が指定されてるため、パディングがない分、要素の内容が広がっちゃうんです…。なので、li要素にはcontent-box
を指定して、widthプロパティの値にパディングを含めないようにすれば万事解決:)。
.menu-list li {
display: table-cell;
min-width: 200px;
vertical-align: top;
box-sizing: content-box;
}
隙間がちょっと広い気がするのでちょっと調整したらば、できあがり!
フッターのサイトマップ
画像の回り込みのところとお知らせ一覧は、テーブルレイアウトではどうしても難しそうなのでパス…。
最後に、フッターの多段組みを、テーブルでレイアウトします。ここもひとまず、フロートしてたところをテーブルレイアウトに置き換えるカタチで、.sitemap-list
にtable
、横幅を100%
に指定して、.group
にtable-cell
を指定します。
@media print, (min-width: 768px) {
.sitemap-list {
display: table;
width: 100%;
margin-left: -16px;
}
.sitemap-list .group {
display: table-cell;
width: 20%;
padding-left: 16px;
}
⋮
やっぱり、テーブルセルにはマージンが適用されないから、全部よこに並んで、最後のグループが潰れちゃいました…。5列は諦めて、6列にするしかないですね…。せめて、グループに横幅を指定するのはやめて、table-layout: fixed
で自動的に均等に割り付けるようにしましょう。
@media print, (min-width: 768px) {
.sitemap-list {
display: table;
table-layout: fixed;
⋮
あと、テーブル要素の横幅が、左へネガティブマージンを指定した分広がっているので、100%
でなくて、calc(100% + 16px)
を指定しなくちゃいけません。
@media print, (min-width: 768px) {
.sitemap-list {
display: table;
table-layout: fixed;
width: calc(100% + 16px);
margin-left: -16px;
}
.sitemap-list .group {
display: table-cell;
padding-left: 16px;
}
}
これにて、テーブルレイアウトで2段組みレイアウト、おしまーい!
Comment & Pingback