flexbox(CSS Flexible Box Layout Module)とは、ユーザーインターフェイスの設計に最適化されたCSSボックスモデルで、複雑なアプリケーションやWebページをレイアウトするために設計されています。子要素を任意の方向に配置することができ、未使用領域を埋めるように成長したり、親ボックスの状態やその変化に伴い、親のオーバーフローを避けるために子要素がフレキシブルに変化します。
このフレックスボックス、筆者自身もそうですが、実際実践でもっとも使用頻度が高いのが横並びの実装だと思います。フレックスボックスの使用が高まる以前にcssでの横並び実装に使用されていたfloatプロパティーなども振り返りながら数あるフレックスボックス関連のプロパティーの中から横並びの実装をメインに選択して記事を書きたいと思います。
フレックスボックスでの3カラム横並び実装
まずは単純に3個の子要素を横に並べる実装を考えます。フレックスボックスで最初の基本になるのが親ボックスへのdisplay:flex;の実装です。この実装がなければ子要素にどんなプロパティーを書いても機能しません。逆に親ボックスにdisplay:flex;を実装した時点でその内部要素は全てCSS Flexible Box Layout Moduleのデフォルトの実装に従うことになります。それだけは述べた上であまり長い説明は嫌気が差すと思うので単純な実装例を先に示したいと思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<!DOCTYPE html> <html lang="ja"> <head> <title>フレックスボックス横並びレイアウト01</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style type="text/css"> <!-- body{ } #parent-box { background:#f9c693; display:flex; padding: 1em; } .box{ background: #a2601d; min-height: 10em; flex-basis: 31%; margin-right: 3.5%; } .box:nth-child(3n) { margin-right: 0; } --> </style> </head> <body> <div id="parent-box"> <div class="box"></div> <div class="box"></div> <div class="box"></div> </div> </body> </html> |
横に3列きれいに並びました。単純に3列並べるだけであればフレックスボックス関連で使用するプロパティーは、親ボックスに実装するdisplay:flex;と子要素の幅を決めるflex-basisのふたつだけです。
flex-basis: 31%;、3つのボックスなので3×31で93%、残りの7%はふたつのボックスのmargin-rightで3.5%づつ分け、.box:nth-child(3n) { margin-right: 0; }で3の倍数の右マージンを0にします。
コンテンツとサイドバーを分けるようなケースであればこのパターンだけで、各子要素のボックスのflex-basisのパーセンテージを変えるだけです。
Flexible Box Layout Module ブラウザの対応状況
骨休めもかねてここで少しフレックスボックスの各ブラウザの対応状況を確認して見ましょう。Use i canで確認できるフレックスボックスの各ブラウザでの対応状況は以下になります。
この記事を読んでくださっている方の使用ブラウザはおそらく、Chrome、Safari、Opera、Firefox辺りだと思うのでなんら問題はないと思うのですが、Internet Explorerは相変わらずの独自実装で、Flexible Box Layout Moduleに関して現行もPartial support(部分的なサポート)です。Internet Explorerを使用しているユーザー向けにホームページやメディアなどを制作されている方は少し注意が必要かもしれません。また、日本国内で対応ブラウザを使用している方の割合は90.31%で10%弱の方が一部対応もしくは未対応のブラウザを使用しているようです。
floatプロパティーでの横並び実装の再確認
フレックスボックスの未対応への対策も兼ねてfloatプロパティーでの実装を今一度確認してみます。floatプロパティーでの横並びの実装は以下になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<!DOCTYPE html> <html lang="ja"> <head> <title>floatプロパティーでの横並びレイアウト01</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style type="text/css"> <!-- #parent-box { background:#f9c693; padding: 1em; clear: both; overflow: hidden; } .box{ background: #a2601d; min-height: 10em; width: 31%; margin-right: 3.5%; float: left; } .box:nth-child(3n) { margin-right: 0; } --> </style> </head> <body> <div id="parent-box"> <div class="box"></div> <div class="box"></div> <div class="box"></div> </div> </body> </html> |
フレックスボックスと比較して、親ボックスはdisplay: flex;をはずして、clear: both;とoverflow: hidden;を追加、子要素は横幅を指定するプロパティーをflex-basisから通常のwidthへと変更、float: left;を追加します。見た目やその他の実装方法はフレックスボックスと何ら変わらないので割愛させて頂きます。
display: flex;とfloatプロパティーの共存
次にFlexible Box Layout Moduleへの未対応への対策なども考え、フレックスボックスとfloatプロパティーとを共存させてみます。と言っても、上記の二つのコードを足し合わせるだけのコードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<!DOCTYPE html> <html lang="ja"> <head> <title>フレックスボックスfloatプロパティーの共存 横並びレイアウト01</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style type="text/css"> <!-- #parent-box { background:#f9c693; clear: both; overflow: hidden; display: flex; padding: 1em; } .box{ background: #a2601d; min-height: 10em; width: 31%; margin-right: 3.5%; float: left; } .box:nth-child(3n) { margin-right: 0; } --> </style> </head> <body> <div id="parent-box"> <div class="box"></div> <div class="box"></div> <div class="box"></div> </div> </body> </html> |
少し勘のある方であれば、ここで少し気になるのはflex-basisプロパティーとwidthプロパティーの関係性ではないでしょうか。flex-basisで検索してみると「flex-basisはwidthを上書きします。flex-basisとwidthを同時に実装した場合はflex-basisが優先される」とのこと。現在のところflex-basisは半分はwidthの代替品だということだと思います。逆に考えればwidthもflex-basisを代替するということです。floatとの共存というテーマを考えればwidthを指定しておくのが通常と考えます。
次のページ3列3行の実装を考えたいとおもいます。