Flexboxを使うとfloatでの面倒なレイアウト作成から解放されます。概ねのブラウザも対応していますし、問題のIE8以下のバージョンも急速にその終焉を迎えました。Flexboxレイアウトを積極的に採用する時が来たように思います。
Flexboxレイアウトではfloatレイアウトでできなかったことやめんどうだったことが簡単にできるようになります。
Flexboxを使う時にまず知っておきたい事は、flexアイテムとflexコンテナの概念です。
flexアイテムがカラムのことで、flexコンテナがカラムを囲む親要素と考えるとわかりやすいです。
簡単なflexレイアウトの基本
例えば次のような例を考えてみます。AとBを横並びにするためにflexを使います。
2つのdivにクラス名を付けて幅200pxと高さ200pxの矩形を作っています。
flex横並び サンプル
HTMLコード
<div class="container"> <div class="col_a">A</div> <div class="col_b">B</div> </div>
CSSコード
.container{ display:flex; background-color: #ccc; } .col_a { background-color: red; width: 200px; height: 200px; } .col_b { background-color: blue; width: 200px; height: 200px; }
divでタグ付けされたAとBを横並べにするCSSの設定は、「display:flex」たったのこれだけです!
ポイントは、「display:flex」はflexコンテナつまり親要素に設定することです。これで簡単に横並びになります。
flex関連のdisplayプロパティの値
- display:flex
- ブロックレベルのflexコンテナボックス
- display:inline-flex
- インラインレベルのflexコンテナボックス
*古いwebkit系では「display:-webkit-box」とする対応が必要です。
横並びと縦並びの指定flex-directionプロパティ
flexレイアウトは横並びと縦並びを切り替える「flex-directionプロパティ」が用意されています。
「flex-direction:column」または「flex-direction:row」を「display:flex」を指定したflexコンテナつまり親要素に付け加えます。
PC用は「flex-direction:row」としておき、モバイル用は「flex-direction:column」とすることで横並びと縦並びを切り替える事ができます。
表示方向プロパティflex-directionの値
カラムの並びを逆転するには「flex-direction」に「row-reverse」または「column-reverse」を指定します。
- flex-direction:row
- 左から右
- flex-direction:row-reverse
- 右から左
- flex-direction:column
- 上から下
- flex-direction:column-reverse
- 下から上
flexレイアウトを使った実例
「CSSでカラムの作成方法〜floatとdisplay:tableの活用」で解説したサンプルをflexで横並びにした例が次のものです。
<section class="column"> <h2 class="column__title">Column3</h2> <div class="column__wrapper"> <div class="column__box"><img class="column__image" src="http://lorempixel.com/300/180/" alt="" /> <div class="column__description"> <div class="column__description-inner"> <div class="column__text"> <h3>小見出し1</h3> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sequi molestias fugiat optio, quasi voluptatum ipsam qui blanditiis <a class="button btn-default" href="#">READ MORE</a> </div> </div> </div> </div> <div class="column__box"><img class="column__image" src="http://lorempixel.com/300/180/" alt="" /> <div class="column__description"> <div class="column__description-inner"> <div class="column__text"> <h3>小見出し2</h3> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sequi molestias fugiat optio, quasi voluptatum ipsam qui blanditiis <a class="button btn-default" href="#">READ MORE</a> </div> </div> </div> </div> <div class="column__box"><img class="column__image" src="http://lorempixel.com/300/180/" alt="" /> <div class="column__description"> <div class="column__description-inner"> <div class="column__text"> <h3>小見出し3</h3> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sequi molestias fugiat optio, quasi voluptatum ipsam qui blanditiis <a class="button btn-default" href="#">READ MORE</a> </div> </div> </div> </div> </div> </section>
@charset "utf-8"; html { font-size: 62.5%; } body { background: #fff; color: #333; text-align: center; font-size: 1.4rem; font-family: "Helvetica Neue", Helvetica, Arial, "Hiragino Kaku Gothic ProN", Meiryo,sans-serif; } *, *::before, *::after { box-sizing: border-box; } .button { display: inline-block; padding: 6px 12px; margin-bottom: 0; font-size: 1.4rem; font-weight: normal; line-height: 1.42857143; text-align: center; text-decoration: none; white-space: nowrap; vertical-align: middle; -ms-touch-action: manipulation; touch-action: manipulation; cursor: pointer; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; border: 1px solid transparent; border-radius: 4px; } .btn-default { color: #333; background-color: #fff; border-color: #ccc; } .btn-default:hover { color: #333; background-color: #e6e6e6; border-color: #adadad; } .column { padding: 80px 0; } /*親要素にdisplay: flex指定するだけ。floatも幅指定も何もいらない。*/ .column__wrapper { display: -webkit-flex; display: flex; width: 100%; margin-top: 60px; } .max { width:100%; } .column__box{ border: 1px solid #333; margin-right: 10px; } .column__box:last-child { margin-right: 0; } .column__image { display: block; width: 100%; } .column__description { width: 100%; padding: 20px; } .column__text { font-size: 1.4rem; line-height: 2; } .column__text .button { width: 60%; margin-top: 20px; padding: 3px; }
カラムの並べ替え
カラムをバラバラな順番にしたい場合は、それぞれのカラムに「order」プロパティで番号を指定します。
SEO上HTMLの並び順を変えたくないけれども、デザイン上の観点から並び順を変更するときなどに便利です。
タブ型のナビでいつも表示ページのナビボタンが左端に移動する仕組みの例です。次の2枚の画像のタブ型ナビに注目してください。
詳細はサンプルのソースを見ていただくことにして、当該ページのナビボタンがいつも左端に来る仕組みは「display:flex」としたコンテナ内のフレックスアイテムの「.selected」が付いたものに「order: -1」を指定するだけで実現できます。
#tab { width: 360px; height: 40px; margin: 0 auto; display:flex; } #tab .selected{ order: -1; }
次のサンプルはECサイトなどで応用できる仕組みです。「orderプロパティ」でカラムの順番を入れ替えています。
カラムの並べ替えを応用したサンプル
HTMLコード
<h1>Flex カラムの並び替え(order)</h1> <section class="column"> <h2 class="column__title">Column1</h2> <div class="column__wrapper"> <div class="column__box max"><img class="column__image" src="http://lorempixel.com/900/540/" alt="" /> <div class="column__description"> <div class="column__text"> <h3>小見出し</h3> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sequi molestias fugiat optio, quasi voluptatum ipsam qui blanditiis <a class="button btn-default" href="#">READ MORE</a> </div> </div> </div> </div> </section><section class="column"> <h2 class="column__title">Column3</h2> <div class="column__wrapper"> <div class="column__box"><img class="column__image" src="http://lorempixel.com/300/180/" alt="" /> <div class="column__description"> <div class="column__description-inner"> <div class="column__text"> <h3>小見出し1</h3> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sequi molestias fugiat optio, quasi voluptatum ipsam qui blanditiis <a class="button btn-default" href="#">READ MORE</a> </div> </div> </div> </div> <div class="column__box"><img class="column__image" src="http://lorempixel.com/300/180/" alt="" /> <div class="column__description"> <div class="column__description-inner"> <div class="column__text"> <h3>小見出し2</h3> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sequi molestias fugiat optio, quasi voluptatum ipsam qui blanditiis <a class="button btn-default" href="#">READ MORE</a> </div> </div> </div> </div> <div class="column__box"><img class="column__image" src="http://lorempixel.com/300/180/" alt="" /> <div class="column__description"> <div class="column__description-inner"> <div class="column__text"> <h3>小見出し3</h3> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sequi molestias fugiat optio, quasi voluptatum ipsam qui blanditiis <a class="button btn-default" href="#">READ MORE</a> </div> </div> </div> </div> </div> </section><section class="column"> <h2 class="column__title">Column4</h2> <div class="column__wrapper"> <div class="column__box a"><img class="column__image" src="http://lorempixel.com/300/180/" alt="" /> <div class="column__description"> <div class="column__description-inner"> <div class="column__text"> <h3>小見出しA</h3> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sequi molestias fugiat optio, quasi voluptatum ipsam qui blanditiis <a class="button btn-default" href="#">READ MORE</a> </div> </div> </div> </div> <div class="column__box b"><img class="column__image" src="http://lorempixel.com/300/180/" alt="" /> <div class="column__description"> <div class="column__description-inner"> <div class="column__text"> <h3>小見出しB</h3> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sequi molestias fugiat optio, quasi voluptatum ipsam qui blanditiis <a class="button btn-default" href="#">READ MORE</a> </div> </div> </div> </div> <div class="column__box c"><img class="column__image" src="http://lorempixel.com/300/180/" alt="" /> <div class="column__description"> <div class="column__description-inner"> <div class="column__text"> <h3>小見出しC</h3> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sequi molestias fugiat optio, quasi voluptatum ipsam qui blanditiis <a class="button btn-default" href="#">READ MORE</a> </div> </div> </div> </div> <div class="column__box d"><img class="column__image" src="http://lorempixel.com/300/180/" alt="" /> <div class="column__description"> <div class="column__description-inner"> <div class="column__text"> <h3>小見出しD</h3> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sequi molestias fugiat optio, quasi voluptatum ipsam qui blanditiis <a class="button btn-default" href="#">READ MORE</a> </div> </div> </div> </div> </div> <div class="column__wrapper"> <div class="column__box"><img class="column__image" src="http://lorempixel.com/300/180/" alt="" /> <div class="column__description"> <div class="column__description-inner"> <div class="column__text"> <h3>小見出しE</h3> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sequi molestias fugiat optio, quasi voluptatum ipsam qui blanditiis <a class="button btn-default" href="#">READ MORE</a> </div> </div> </div> </div> <div class="column__box"><img class="column__image" src="http://lorempixel.com/300/180/" alt="" /> <div class="column__description"> <div class="column__description-inner"> <div class="column__text"> <h3>小見出しF</h3> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sequi molestias fugiat optio, quasi voluptatum ipsam qui blanditiis <a class="button btn-default" href="#">READ MORE</a> </div> </div> </div> </div> <div class="column__box"><img class="column__image" src="http://lorempixel.com/300/180/" alt="" /> <div class="column__description"> <div class="column__description-inner"> <div class="column__text"> <h3>小見出しG</h3> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sequi molestias fugiat optio, quasi voluptatum ipsam qui blanditiis <a class="button btn-default" href="#">READ MORE</a> </div> </div> </div> </div> <div class="column__box"><img class="column__image" src="http://lorempixel.com/300/180/" alt="" /> <div class="column__description"> <div class="column__description-inner"> <div class="column__text"> <h3>小見出しH</h3> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sequi molestias fugiat optio, quasi voluptatum ipsam qui blanditiis <a class="button btn-default" href="#">READ MORE</a> </div> </div> </div> </div> </div> </section>
CSSコード
@charset "utf-8"; html { font-size: 62.5%; } body { background: #fff; color: #333; text-align: center; font-size: 1.4rem; font-family: "Helvetica Neue", Helvetica, Arial, "Hiragino Kaku Gothic ProN", Meiryo,sans-serif; } *, *::before, *::after { box-sizing: border-box; } .button { display: inline-block; padding: 6px 12px; margin-bottom: 0; font-size: 1.4rem; font-weight: normal; line-height: 1.42857143; text-align: center; text-decoration: none; white-space: nowrap; vertical-align: middle; -ms-touch-action: manipulation; touch-action: manipulation; cursor: pointer; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; border: 1px solid transparent; border-radius: 4px; } .btn-default { color: #333; background-color: #fff; border-color: #ccc; } .btn-default:hover { color: #333; background-color: #e6e6e6; border-color: #adadad; } .column { padding: 80px 0; } .column__wrapper { display: -webkit-flex; display: flex; flex-direction: row; width: 100%; margin-top: 60px; } .a { order: 2; } .b, .d { order: 3; } .c { order: 1; } .max { width:100%; } .column__box{ border: 1px solid #333; margin-right: 10px; } .column__box:last-child { margin-right: 0; } .column__image { display: block; width: 100%; } .column__description { width: 100%; padding: 20px; } .column__text { font-size: 1.4rem; line-height: 2; } .column__text .button { width: 60%; margin-top: 20px; padding: 3px; }
横並びflexアイテムの水平方向の位置調整
flexコンテナの中に固定サイズのflexアイテムを配置すると、余分な余白ができたりします。その場合flexアイテムの配置を左寄せ、右寄せ、中央寄せに設定できます。さらに、各flexアイテムの間隔を自動で調整する設定もできます。
そのプロパティが「justify-content」プロパティです。ポイントはflexコンテナに対して「justify-content」プロパティを指定することです。
左寄せ
左寄せは特に指定をしません。
左寄せの横並びのサンプル
HTMLコード
<div class="container"> <div class="col_a">A</div> <div class="col_b">B</div> <div class="col_c">C</div> <div class="col_d">D</div> </div>
display: flexと設定すれば左寄せで横並びに配置されます。flexアイテムにはそれぞれ200pxのサイズ指定をしています。flexコンテナの方は特に幅指定をしていないのでいっぱいに広がった状態になっています。
CSSコード
.container { display: flex; background-color: #ccc; } .col_a { background-color: red; width: 200px; height: 200px; } .col_b { background-color: blue; width: 200px; height: 200px; } .col_c { background-color: yellow; width: 200px; height: 200px; } .col_d { background-color: green; width: 200px; height: 200px; }
右寄せ
flexアイテムを右寄せにするには、flexコンテナにjustify-contentプロパティを使い、値にflex-endを指定します。
右寄せの横並びのサンプル
CSSコード
.container { display: flex; background-color: #ccc; justify-content:flex-end; }
中央寄せ
flexアイテムを右寄せにするには、flexコンテナにjustify-contentプロパティを使い、値にcenterを指定します。
中央寄せの横並びのサンプル
CSSコード
.container { display: flex; background-color: #ccc; justify-content:center; }
各flexアイテムに余白を分割し、両端の余白は無し
各flexアイテムに余白を分割し、両端の余白は無しにするspace-betweenという便利な値があります。
両端なしの自動余白分割のサンプル
CSSコード
.container { display: flex; background-color: #ccc; justify-content:space-between; }
両端と各flexアイテムに余白を分割
各flexアイテムに余白を分割し、更に両端にも余白を付ける値が、space-aroundです。
両端余白付きの自動余白分割のサンプル
CSSコード
.container { display: flex; background-color: #ccc; justify-content:space-around; }
縦並びflexアイテムの垂直方向の位置調整
Flexboxを縦に並べるには「flex-direction:column」を使いました。縦並びにしたときに、「justify-content」プロパティを使うと垂直方向に位置を設定できます。
縦並び上から基準に並べる
上側を基準に縦並びをするには、「justify-content」プロパティは必要ありません。
縦並び上から基準に並べたサンプル
CSSコード
.container { display: flex; flex-direction:column; background-color: #ccc; height:1000px; }
縦並び下から基準に並べる
縦並び下から基準に並べる
CSSコード
.container { display: flex; flex-direction:column; background-color: #ccc; justify-content:flex-end; height:1000px; }
縦並び中央から基準に並べる
縦並び中央から基準に並べる
CSSコード
.container { display: flex; flex-direction:column; background-color: #ccc; justify-content:center; height:1000px; }
縦並び自動分割に並べる両端スペースなし
縦並び自動分割に並べる両端スペースなし
CSSコード
.container { display: flex; flex-direction:column; background-color: #ccc; justify-content:space-between; height:1000px; }
縦並び自動分割に並べる両端スペースあり
縦並び自動分割に並べる両端スペースあり
CSSコード
.container { display: flex; flex-direction:column; background-color: #ccc; justify-content:space-around; height:1000px; }
横並びflexアイテムの垂直方向の位置調整
今度は縦方向にスペースがある場合にどこに表示するか設定します。この場合は、「align-items」プロパティを使用します。
次のサンプルは横方向と縦方向両方にスペースがある場合の水平方向と垂直方向の位置指定したものです。
横並びflexアイテムの垂直方向上、水平方向左の位置調整
横並びflexアイテムの垂直方向上、水平方向左の位置調整のサンプル
CSSコード
.container { display: flex; background-color: #ccc; height:1000px; width:1000px; }
横並びflexアイテムの垂直方向上、水平方向自動調整
横並びflexアイテムの垂直方向上、水平方向自動調整のサンプル
CSSコード
.container { display: flex; justify-content:space-around; align-items:flex-start; background-color: #ccc; height:1000px; width:1000px; }
横並びflexアイテムの垂直方向下、水平方向自動調整
横並びflexアイテムの垂直方向下、水平方向自動調整のサンプル
CSSコード
.container { display: flex; justify-content:space-around; align-items:flex-end; background-color: #ccc; height:1000px; width:1000px; }
横並びflexアイテムの垂直方向中央、水平方向自動調整
横並びflexアイテムの垂直方向中央、水平方向自動調整
CSSコード
.container { display: flex; justify-content:space-around; align-items:center; background-color: #ccc; height:1000px; width:1000px; }
横並びflexアイテムの垂直方向自動調整、水平方向自動調整
「align-items:stretch」を指定すると、flexアイテムに高さを指定していないと、flexアイテムの高さがflexコンテナの高さいっぱいに広がります。
次のサンプルではAとBは高さを指定していません。それ以外は高さを200pxに指定しています。ABのみflexコンテナいっぱいに広がります。
横並びflexアイテムの垂直方向自動調整、水平方向自動調整
CSSコード
.container { display: flex; justify-content:space-around; align-items:stretch; background-color: #ccc; height:1000px; width:1000px; }
flex-growとflex-shrink
flexコンテナの大きさがflexアイテムの合計の大きさより大きい場合は大きく余白が空きます。このときにflex-growをflexアイテムに設定すると自動でflexアイテムの幅が伸びてちょうど良いサイズになってくれます。
逆にflexコンテナのサイズがflesアイテムの合計サイズより小さい場合はflex-shrinkを使うことで自動でflexアイテムのサイズが縮んでくれるものです。
flex-grow
flex-growプロパティはflexアイテムの伸長係数を決めるもので、数値で指定します。
例えば、すべてのflexアイテムに「flex-grow:1」を設定するとすべてのflexアイテムが均一に拡大して余白を埋めてくれます。
flex-grow:1のサンプル
CSSコード
.container { display: flex; background-color: #ccc; } .col_a { background-color: red; width: 200px; height: 200px; flex-grow:1; } .col_b { background-color: blue; width: 200px; height: 200px; flex-grow:1; } .col_c { background-color: yellow; width: 200px; height: 200px; flex-grow:1; } .col_d { background-color: green; width: 200px; height: 200px; flex-grow:1; }
flex-growの値を別々に設定すると、その数値に応じてそれぞれのflexボックスの幅が調整されます。その仕組みは残った余白部分をflex-growで指定した数値の比率に分割されるようになっています。
CSSコード
.container { display: flex; background-color: #ccc; } .col_a { background-color: red; width: 200px; height: 200px; flex-grow:1; } .col_b { background-color: blue; width: 200px; height: 200px; flex-grow:3; } .col_c { background-color: yellow; width: 200px; height: 200px; flex-grow:2; } .col_d { background-color: green; width: 200px; height: 200px; flex-grow:1; }
flex-shrink
「flex-shrink:数字」でflexアイテムの幅を自動で縮小変更できます。flexコンテナにぴったり入るように自動で縮小調整されます。flex-shrinkの値を変更するとその数値に応じてそれぞれのflexボックスの幅が調整されます。その仕組みは不足した余白部分をflex-shrinkで指定した数値の比率に分割されるようになっています。
flex-shrinkのサンプル
CSSコード
.container { display: flex; background-color: #ccc; width:600px; } .col_a { background-color: red; width: 200px; height: 200px; } .col_b { background-color: blue; width: 200px; height: 200px; flex-shrink:3; } .col_c { background-color: yellow; width: 200px; height: 200px; } .col_d { background-color: green; width: 200px; height: 200px; }
flexプロパティ
flexプロパティはflex-growと flex-shrink、そしてflex-basisの短縮記法です。
値はスペースで区切って記述され、flex-grow、flex-shrink、flex-basisの順番になります。
flex-basisプロパティとはすでに指定しているflexアイテムのwidthの値をflex-basisの値に書き換えるものです。すでにwidhで幅を指定しているのに、わざわざflex-basisを使う必要はないと考えてしまいますが、Flexboxではwidhで幅を指定しても、先のflex-growやflex-shrinkを使われると指定していた幅が無効になってしまいます。
そんなときに、flex-basisを使えばある一定の条件のもとwidthの値を固定することができるわけです。
サンプル1 flex-grow、flex-shrinkの値を1にしてflex-basisに固定の値を設定
flex-grow、flex-shrinkの値を1にしてflex-basisに固定の値を設定するとフレックスコンテナがflex-basisの固定値の合計よりも拡大縮小したら、フレックスアイテムは固定幅の比率を保ち続けて拡大縮小します。
CSSコード
.first{ flex:1 1 250px; } .second{ flex:1 1 200px; } .third{ flex:1 1 150px; margin-right:0; }
サンプル2 flex-growの値を0、flex-shrinkの値を1にしてflex-basisに固定の値を設定
flex-growの値を0、flex-shrinkの値を1にしてflex-basisに固定の値を設定するとフレックスコンテナがflex-basisの固定値の合計よりも拡大してもフレックスアイテムの固定幅は保ち続けます。けれども、縮小した場合はフレックスアイテムは固定の幅の比率を保ちながら縮小します。
CSSコード
.first{ flex:0 1 250px; } .second{ flex:0 1 200px; } .third{ flex:0 1 150px; margin-right:0; }
サンプル3 flex-growの値を1、flex-shrinkの値を0にしてflex-basisに固定の値を設定
flex-growの値を1、flex-shrinkの値を0にしてflex-basisに固定の値を設定するとフレックスコンテナがflex-basisの固定値の合計よりも縮小してもフレックスアイテムの固定幅は保ち続けます。けれども、拡大した場合はフレックスアイテムは固定の幅の比率を保ちながら拡大します。
CSSコード
.first{ flex:1 0 250px; } .second{ flex:1 0 200px; } .third{ flex:1 0 150px; margin-right:0; }
サンプル4 flex-grow、flex-shrinkの値を0にしてflex-basisに固定の値を設定
flex-grow、flex-shrinkの値を0にしてflex-basisに固定の値を設定するとフレックスコンテナがflex-basisの固定値の合計よりも拡大縮小してもフレックスアイテムは固定の幅を保ち続けます。
CSSコード
.first{ flex:0 0 250px; } .second{ flex:0 0 200px; } .third{ flex:0 0 150px; margin-right:0; }
コメントを投稿するにはログインしてください。