Flexbox (Flexible Box Layout)
作成日:2018年4月13日
Flexbox (Flexible Box Layout Module) は CSS3 から導入された柔軟なボックスレイアウトを可能にするレイアウトモードです。従来の float や clearfix では表現できなかったレイアウトが、Flexbox では簡単に表現できるようになっています。
CSS Flexible Box Layout Module Level 1
CSS Flexible Box Layout Module Level 1 日本語訳
対応ブラウザ
2017年9月の時点での「caniuse.com/#feat=flexbox」では全てのモダンブラウザで Flexbox を使うことができるようです。IE11 では一部バグを残していますが、Edghe では対応済みになっています。
Flexbox の基本的な使い方
Flexbox では、要素に display: flex(インライン要素に使う場合は、display: inline-flex) を指定することでその要素を「フレックスコンテナ(Flex Container)」として扱えるようにします。
これによりその要素の子要素は自動的に「フレックスアイテム(Frex Item)」と呼ばれる構造体として扱えるようになり、フレックスアイテム、フレックスコンテナのそれぞれに対して Flexbox のプロパティが使用可能になります。
Flexbox では、フレックスコンテナとフレックスアイテムのプロパティを使ってレイアウトを指定していきます。
HTML ではフレックスコンテナと呼ばれる親要素の中に、フレックスアイテムと呼ばれる子要素を入れてマークアップします。以下の例では親要素である「flex_container」というクラスを付与した div 要素の中に、子要素である「flex_item」というクラスを付与した div 要素が入っています。
<div class="flex_container"> <div class="flex_item">Flex Item 1</div> <div class="flex_item">Flex Item 2</div> <div class="flex_item">Flex Item 3</div> </div>
Flexbox の指定をしていないので、子要素が縦に並んでいる状態になっています。また、この例では見易いように背景色やマージン等を設定しています。
親要素(フレックスコンテナ)に display: flex; を指定するだけで、子要素が左寄せ・横並びのレイアウト(デフォルトの flex-direction : row)になります。
.flex_container { display:flex; }
例えば以下のような HTML がある場合、Flexbox を使えば float や clearfix を使わずに簡単にレイアウトすることができます。
<div class="flex_containter"> <img src="../images/sample_img.jpg" alt=""> <div class="description"> <h4>Title</h4> <p> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Magnam totam saepe provident cum suscipit explicabo architecto earum necessitatibus nam corporis? </p> </div> </div>
.flex_containter { display:flex; /* Flexbox の指定 */ margin: 20px 0; border: 1px solid #CCC; } .flex_containter img { margin: 10px; } .description { margin: 0 20px; }

Title
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Magnam totam saepe provident cum suscipit explicabo architecto earum necessitatibus nam corporis?
以下のような複数カラムのレイアウトが簡単に作成できます。
CSS では実際には、マージンやボーダー、背景色を指定していますが、レイアウト的にはとてもシンプルな記述で済みます。(2カラムレイアウト、3カラムレイアウト)
<div class="row"> <div class="col">column 1</div> <div class="col">column 2</div> <div class="col">column 3</div> </div>
.row { display: flex; } .col { width: 100%; height: 100px; }
以下は Flex コンテナのプロパティにデフォルト値を指定した例です。これらのプロパティを使って詳細なレイアウトを指定することができます。
.flex_container { display: flex; flex-direction: row; flex-wrap: nowrap; justify-content: flex-start; align-items: stretch; align-content: stretch; }
また、Flex コンテナの子要素の Flex アイテムのプロパティを使って更に詳細なレイアウトを指定することができます。以下は Flex アイテムのプロパティにデフォルト値を指定した例です。
.flex_item { order: 0; flex-grow: 0; flex-shrink: 1; flex-basis: auto; align-self: auto; }
※ Flexbox 関連のプロパティでは、ドキュメントの文字方向(横書き・縦書き、左から右・右から左)に配置が依存する部分があります。この例では、横書きで ltr(左から右方向で、テキストは下に折り返し)を前提にしています。
Flexbox の用語
Flexbox のレイアウトは、主軸 (main axis)と交差軸 (cross axis)という2つの軸によって決定されます。初期状態では、左から右方向の軸が主軸、上から下方向の軸が交差軸になります。
以下は flex-direction プロパティの値が row(左から右の横並び)の場合の Flex Container の図です。
(参考:CSS flexible box の利用 /developer.mozilla.org )
- Flex Container (Flex コンテナ)
- flex アイテムを含む親要素です。flex コンテナは display プロパティの値に flex または inline-flex を指定することによって定義されます。
- Flex Item (Flex アイテム)
- flex コンテナの子要素が自動的に flex アイテムになります。flex コンテナの直接の子要素になっているテキストは、無名の flex アイテムに包まれています。
- Axis (軸)
- flexible box は2つの軸を持っています。主軸 (main axis) は flex アイテム対して平行な軸で、交差軸 (cross axis) は main axis に対して垂直な軸です。
- Direction (方向)
- flex コンテナの端にあたる main start/main end および cross start/cross end は、flex アイテムのフローの始点と終端を表します。flex アイテムは writing-mode で定義した向き (left-to-right や right-to-left など) をもとに、主軸や交差軸に従います。
Flexbox のプロパティ
Flexbox のプロパティはFlex Container に適用するプロパティと、Flex Item に適用するプロパティがあります。
以下にあるサンプルは、おおまかな動作の確認のためのもので、正確とは限りません。以下のサイトに flexbox のレイアウトを試せるツールがあります。
Flex Container のプロパティ
プロパティ | 概要 | 値と意味 |
---|---|---|
flex-direction | Flex アイテムを並べる方向を設定(主軸を定義) |
|
flex-wrap | Flex アイテムの折り返しとその方向の指定 |
|
flex-flow | flex-direction と flex-wrap を同時に指定するショートハンドプロパティ | デフォルトは row nowrap。最初の値が flex-direction の値、スペースを空けて2つ目の値が flex-wrap の値になります。 |
justify-content | 主軸(main axis)方向の整列位置を指定。 |
|
align-items | 交差軸(cross axis)方向の整列位置を指定。 |
|
align-content | 折り返した Flex アイテム の交差軸(cross axis)方向の整列位置を指定。 |
|
flex-direction
Flex アイテムを並べる方向を設定するプロパティで、主軸を定義します。デフォルト(初期値)は row で、正順(ドキュメントの方向:この例では ltr 左から右方向)の横並びになります。
- row:左を始端に右へ横並び(デフォルト)
- row-reverse:右を始端に左へ横並び
- column:上を始端に下へ縦並び
- column-reverse:下を始端に上へ縦並び
flex-direction:
以下はこの例の基本的なマークアップです。
.flex_container {
display: flex;
flex-direction: row;
max-width: 550px;
}
.flex_item {
margin: 30px 20px;
padding: 5px;
}
<div class="flex_container"> <div class="flex_item">Flex Item 1</div> <div class="flex_item">Flex Item 2</div> <div class="flex_item">Flex Item 3</div> </div>
flex-wrap
Flex アイテムの折り返しとその方向を決めるプロパティです。
デフォルトの nowrap では Flex コンテナの大きさが、Flex アイテムの大きさの合計より小さくても1行に収めようとするため、Flex アイテムの大きさは適宜縮小されます。(flex-direction が column または column-reverse の場合は、1列に収めようとします)。
このプロパティは Flex コンテナと Flex アイテムの大きさが関係してくるため少し複雑です。 flex-direction が row または row-reverse の場合は幅に依存し、flex-direction が column または column-reverse の場合は高さに依存します。
サンプルの都合上、flex-direction の値が、row または row-reverse の場合と、column または column-reverse に分けています。
flex-direction が row または row-reverse の場合の例
- nowrap:折り返さない(デフォルト)。Flex アイテムを全て1行に収めようとする。
- wrap:Flex コンテナの幅に収まらない場合、折り返す。
- wrap-reverse:Flex コンテナの幅に収まらない場合、逆方向に折り返す。
flex-direction:
flex-wrap:
<div> <div class="flex_container"> <div class="flex_item">Flex Item 1</div> <div class="flex_item">Flex Item 2</div> <div class="flex_item">Flex Item 3</div> <div class="flex_item">Flex Item 4</div> <div class="flex_item">Flex Item 5</div> </div> </div>
.flex_container { display: flex; flex-direction: row; flex-wrap: nowrap; }
flex-direction が column または column-reverse の場合の例
nowrap の場合は、高さは指定していませんが(この例の場合、小さな値を指定すると Flex アイテムがはみ出てしまいます)、その他の場合は、Flex コンテナの高さを一定(360px)にしています。
Flex コンテナと Flex アイテムの大きさ(高さや幅、マージン、パディングなど)により、動作が変わってきます。
- nowrap:折り返さない(デフォルト)。Flex アイテムを全て1列に収めようとする。
- wrap:Flex コンテナの幅に収まらない場合、折り返す。
- wrap-reverse:Flex コンテナの幅に収まらない場合、逆方向に折り返す。
flex-direction:
flex-wrap:
<div> <div class="flex_container"> <div class="flex_item">Flex Item 1</div> <div class="flex_item">Flex Item 2</div> <div class="flex_item">Flex Item 3</div> <div class="flex_item">Flex Item 4</div> <div class="flex_item">Flex Item 5</div> </div> </div>
.flex_container { display: flex; flex-direction: column; flex-wrap: nowrap; height: auto; }
flex-flow
flex-flow は、Flex アイテムの配置方向(flex-direction)と折り返し(flex-wrap)をまとめて指定するショートハンドプロパティです。
値は半角スペースで区切って指定します(任意の順序で指定可能)。省略した場合は各プロパティの初期値が適用されます。
.flex-container { flex-flow: flex-directionの値 flex-wrapの値; /* 初期値は row nowrap */ }
以下は、flex-direction に column を、flex-wrap に wrap を指定した例です。
.flex-container { display: flex; flex-flow: column wrap; }
上記で指定した flex-flow プロパティは、各プロパティを以下のように指定した場合と同じです。
.flex-container { display: flex; flex-direction: column; flex-wrap: wrap; }
値を1つだけ指定することもできますが、その場合、省略した方のプロパティには初期値が適用されます。
.flex-container { display: flex; flex-flow: column; /*flex-flow: column nowrap; と同じ*/ }
justify-content
主軸(main axis)方向の整列位置を指定するプロパティで、flex アイテムをどのように主軸に沿ってレイアウトするかを定義します。デフォルトは flex-start です。
- flex-start:始端揃え(デフォルト)
- flex-end:終端揃え
- center:中央揃え
- space-between:両端揃えで均等割り(最初の Flex アイテムを始端に、最後の Flex アイテムを終端に揃えて残りを均等配置)
- space-around:均等割り(全てを均等割り配置)
以下の例では、flex-direction の値が、column/column-reverse の場合は高さ(500px)を指定しています。(高さを auto にしてしまうと違いがわからないため)
flex-direction:
flex-wrap: nowrap
justify-content:
<div> <div class="flex_container"> <div class="flex_item">Flex Item 1</div> <div class="flex_item">Flex Item 2</div> <div class="flex_item">Flex Item 3</div> </div> </div>
.flex_container { display: flex; flex-direction: row; flex-wrap: nowrap; justify-content: flex-start; height: auto; }
align-items
交差軸(cross axis)方向の整列位置を指定するプロパティで、flex アイテムをどのように交差軸に沿ってレイアウトするかを定義します。デフォルトは stretch です。
但し、stretch が有効なのは Flex アイテムに高さが指定されていない場合のみになります。
- flex-start:始端揃え。Flex コンテナの交差軸 (cross axis) の起点(cross start)に揃えます。
- flex-end:終端揃え。Flex コンテナの交差軸 (cross axis) の終点(cross end)に揃えます。
- center:中央揃え。Flex コンテナの交差軸 (cross axis) の中央に揃えます。
- baseline:ベースライン揃え(Flex アイテムごとのテキストのベースラインが揃うようにします)
- stretch:高さを拡張(デフォルト)。Flex アイテムに高さが指定されていない場合、全ての Flex アイテムの高さを Flex コンテナの高さまで広げます。
以下の例では、改行を入れたり、文字の大きさを変えたりして、それぞれの Flex アイテムの高さを異なるようにしています(高さは指定していません)。
flex-direction:
flex-wrap: nowrap
align-items:
Flex Item 2
+
+
<div> <div class="flex_container"> <div class="flex_item">Flex Item 1</div> <div class="flex_item"> <p>Flex Item 2</p> <p>+</p> <p>+</p> </div> <div class="flex_item">Flex Item 3<br> </div> </div> </div>
.flex_container { display: flex; flex-direction: row; flex-wrap: nowrap; align-items: flex-start; height: auto; } .flex_item { height: auto; }
align-content
折り返した Flex アイテム の交差軸(cross axis)方向の整列位置を指定(制御)するプロパティです。flex-wrap の値が、wrap または wrap-reverse の場合にのみ有効になります。
以下のサンプルは、違いがわかりやすいように flex-direction が row または row-reverse の場合は Flex コンテナの高さを 550px に、column または column-reverse の場合は Flex コンテナの高さを 360px にしています。
align-content:stretch は、align-items 同様 Flex アイテムに高さが指定されていない場合のみ有効です。
- flex-start:始端揃え
- flex-end:終端揃え
- center:中央揃え
- space-between:両端揃えで均等割り
- space-around:均等割り
- stretch:高さ(幅)を拡張(デフォルト)
flex-direction:
flex-wrap:
align-content:
Flex Item 2
<div> <div class="flex_container"> <div class="flex_item">Flex Item 1</div> <div class="flex_item""> <p>Flex Item 2</p> </div> <div class="flex_item">Flex Item 3<br> </div> <div class="flex_item">Flex Item 4<br> <br> </div> <div class="flex_item">Flex Item 5</div> </div> </div>
.flex_container { display: flex; flex-direction: row; flex-wrap: nowrap; align-content: flex-start; height: auto; } .flex_item { height: auto; }
Flex Item のプロパティ
プロパティ | 概要 | 値と意味 |
---|---|---|
order | Flex アイテムの並び順を指定 | 整数値(デフォルトは 0)。 少ない値ほど前に配置される。 負の値を指定可。 |
flex-grow | Flex アイテム全体の幅が Flex コンテナの幅に満たない場合に伸びる比率を指定 | 数値(デフォルトは 0)。 負の値は無効 |
flex-shrink | Flex アイテム全体の幅が Flex コンテナの幅より大きい場合に縮む比率を指定 | 数値(デフォルトは 1)。 負の値は無効。 0 の場合は縮まずにオリジナルサイズを維持 |
flex-basis | Flex アイテムの基準となる幅(Flex アイテムの初期 main size)を設定 | px などの単位付きの数値や、親の Flex コンテナの main size に対するパーセンテージで指定。 デフォルトは auto。 |
flex | flex-grow、flex-shrink、flex-basis を同時に指定するショートハンドプロパティ | flex-grow, flex-shrink, flex-basis プロパティの順で指定 |
align-self | Flex アイテムの交差軸(cross axis)方向の整列位置を指定。Flex コンテナに指定する align-items と同じ機能ですが、親要素に記述する align-items よりも優先されます。 |
|
order
Flex アイテムは通常 HTML の記述順に配置されますが、order プロパティーを使うことで Flex アイテムを任意の順で並べ替えることができます。
order プロパティは、Flex コンテナ内で Flex アイテムを配置する順序を整数で指定します。要素は、order の値の昇順(小さい順)に配置され、order の値が同じ要素は、ソースコード内で現れる順に配置されます。負の値も指定できます。
.fi1 { order: 2; } .fi2 { order: 3; } .fi3 { order: 1; }
order プロパティの初期値は 0 なので、0 よりも少ない値を指定してすると一番前に配置されます。
以下のサンプルでは、order の値に -5~5 を指定することができるようになっています。また、Flex コンテナには justify-content: space-around; を指定して均等配置にしています。
flex-direction:
order : (Flex Item 1)
order : (Flex Item 2)
order : (Flex Item 3)
order : (Flex Item 4)
order : (Flex Item 5)
<div class="flex_container"> <div class="flex_item fi1">Flex Item 1</div> <div class="flex_item fi2">Flex Item 2</div> <div class="flex_item fi3">Flex Item 3</div> <div class="flex_item fi4">Flex Item 4</div> <div class="flex_item fi5">Flex Item 5</div> </div>
.flex_container { display: flex; justify-content: space-around; } .flex_item { margin:0; padding:0; }
flex-grow
Flex アイテム全体の幅が Flex コンテナの主軸(main axis)の幅に満たない場合に伸びる比率を数値で指定します(デフォルトは 0)。負の値は無効です。
但し、伸び率はフレックスコンテナの幅や flex-wrap プロパティの折り返しの指定、flex-basis プロパティ(Flex アイテムの基準となる幅)に影響され、、自動的に調整されます。
Flex コンテナにスペースが余っている場合、それぞれの Flex アイテムには flex-grow の比率の指定に従って余ったスペースが分配されます。
下図の場合、それぞれの Flex アイテムの flex-grow の値が 1 の例で、比率は 1:1:1 になり、余白は 3 等分(1 + 1 +1)され、それぞれの Flex アイテムに分配されます。
下図の場合、それぞれの Flex アイテムの flex-grow の値は 1, 2, 1 の例で、比率は 1:2:1 になり、余白は 4 等分(1 + 2 +1)され、それぞれの比率に従って Flex アイテムに分配されます。
※以下の例は、大まかな雰囲気をつかむためのもので、表示される幅の値は正確ではありません。指定する項目の順番等により異なる結果が表示される場合があります。
flex-grow : flex-basis : (Flex Item 1)
flex-grow : flex-basis : (Flex Item 2)
flex-grow : flex-basis : (Flex Item 3)
width: px
fb:
width: px
fb:
width: px
fb:
<div class="flex_container"> <div class="flex_item">Flex Item 1</div> <div class="flex_item">Flex Item 2</div> <div class="flex_item">Flex Item 3</div> </div>
.flex_container { display: flex; } .flex_item { flex-grow: 0; /*初期値*/ margin:0; padding:0; }
flex-shrink
Flex アイテム全体の幅が Flex コンテナの主軸(main axis)の幅より大きい場合に縮む比率を数値で指定します(デフォルトは 1)。負の値は無効です。
また、0 を指定した場合は、縮まずにオリジナルサイズを維持します。flex-grow とは逆で、値が大きいほど幅が狭くなります。
下図の場合、それぞれの Flex アイテムの flex-shrink の値が 1 の例で、比率は 1:1:1 になり、コンテナからはみ出した幅を 3 等分(1 + 1 +1)した分をそれぞれのFlex アイテムから差し引きます。
※以下の例は、大まかな雰囲気をつかむためのもので、表示される幅の値は正確ではありません。指定する項目の順番等により異なる結果が表示される場合があります。
flex-shrink : flex-basis : (Flex Item 1)
flex-shrink : flex-basis : (Flex Item 2)
flex-shrink : flex-basis : (Flex Item 3)
width: px / flex-basis:
width: px / flex-basis:
width: px / flex-basis:
<div class="flex_container"> <div class="flex_item">Flex Item 1 <br>width: xx px / flex-basis: xxx</div> <div class="flex_item">Flex Item 2 <br>width: xx px / flex-basis: xxx</div> <div class="flex_item">Flex Item 3 <br>width: xx px / flex-basis: xxx</div> </div>
.flex_container { display: flex; } .flex_item { flex-shrink: 0; /*初期値*/ }
flex-basis
Flex アイテムの基準となる幅(Flex アイテムの初期 main size)を設定します。
px, em などの単位付きの数値や、親の Flex コンテナの main size に対するパーセンテージで指定します。デフォルトは auto です。
auto は 「自身の width または height プロパティを参照する」という意味になります。また、自動サイズ設定(幅をコンテンツの横幅から決定)を行うための 「content」キーワードが導入されていますが、まだ普及はしていないようです。
親要素のサイズや flex-grow、flex-shrink が指定されている場合、flex-basis で指定した幅で表示されるとは限らず、自動的に調整されレイアウトされます。flex-basis は width や height のようにサイズを固定するわけではありません。
flex-basis に 0 を指定し、flex-glow で比率を指定すると、その割合でレイアウトされます。
また、flex-shrink 値が 0 の場合、flex-basis で指定した幅は伸縮しないため、親要素からはみ出して表示される可能性があります。
※以下の例は、大まかな雰囲気をつかむためのもので、表示される幅の値は正確ではありません。指定する項目の順番等により異なる結果が表示される場合があります。
flex-grow : flex-shrink : flex-basis : (Flex Item 1)
flex-grow : flex-shrink : flex-basis : (Flex Item 2)
flex-grow : flex-shrink : flex-basis : (Flex Item 3)
width: px
fb:
width: px
fb:
width: px
fb:
<div class="flex_container"> <div class="flex_item">Flex Item 1</div> <div class="flex_item">Flex Item 2</div> <div class="flex_item">Flex Item 3</div> </div>
.flex_container { display: flex; } .flex_item { flex-basis: auto; /*初期値*/ margin:0; padding:0; }
flex
flex-grow、flex-shrink、flex-basis を同時に指定するショートハンドプロパティです。
デフォルトは「0 1 auto」で、「Flex アイテムが親要素に合わせて拡大はしないが、縮小され、基準サイズはコンテンツが収まる幅にする」と言うような意味になります。
それぞれの値は半角スペースで区切って指定します。省略した場合は各プロパティのデフォルト値が適用されます。値を3つ指定する場合は、flex-grow、flex-shrink、flex-basis の順で指定します。
また、3つのプロパティの値を指定する代わりに以下のキーワードを指定することができます。
- initial
- 「0 1 auto」と同じ意味です。
flex-grow: 0; flex-shrink: 1; flex-basis: auto;
- auto
- 「1 1 auto」と同じ意味です。
flex-grow: 1; flex-shrink: 1; flex-basis: auto;
- none
- 「0 0 auto」と同じ意味です。
flex-grow: 0; flex-shrink: 0; flex-basis: auto;
- 正の整数の値1つ
- 「整数の値 1 0」と同じ意味です。(flex-basis は 0 になります)
flex-grow: 整数の値; flex-shrink: 1; flex-basis: 0;
以下は指定例です。
/* 値を 3 つ指定: flex-grow | flex-shrink | flex-basis */ flex: 2 2 30%; /* 値を 2 つ指定: flex-grow | flex-basis(単位付き) */ flex: 1 30px; /* 値を 2 つ指定: flex-grow | flex-shrink */ flex: 2 2; /* 単位がない数値を 1 つ指定: flex-grow */ flex: 2; /* flex: 2 1 0 を指定したのと同じ */ /* 幅または高さを 1 つ指定: flex-basis */ flex: 5em; flex: 20px; flex: auto; flex: content; /* 0 1 auto */ flex: initial;
align-self
Flex アイテムの交差軸(cross axis)方向の整列位置を指定します。Flex コンテナに指定する align-items と同じ機能ですが、親要素に記述する align-items よりも優先されます。
- auto:親要素の align-items の値を継承(デフォルト)
- flex-start:始端揃え。Flex コンテナの交差軸 (cross axis) の起点(cross start)に揃えます。
- flex-end:終端揃え。Flex コンテナの交差軸 (cross axis) の終点(cross end)に揃えます。
- center:中央揃え。Flex コンテナの交差軸 (cross axis) の中央に揃えます。
- baseline:ベースライン揃え。Flex アイテム内のベースラインの位置に揃えるように、Flex コンテナの交差軸 (cross axis) の起点(cross start)からアイテムの位置を揃えます。
- stretch:高さを拡張。Flex コンテナの交差軸 (cross axis) の幅に合わせて伸縮して表示されます。
height: Flex コンテナ
align-self: Flex Item 1
align-self: Flex Item 2
align-self: Flex Item 3
Flex Item 2
Flex Item 3
Flex Item 3
<div class="flex_container"> <div class="flex_item">Flex Item 1</div> <div class="flex_item">Flex Item 2<br>Flex Item 2</div> <div class="flex_item">Flex Item 3<br>Flex Item 3<br>Flex Item 3</div> </div>
.flex_container { display: flex; justify-content: space-around; height:200px; } .flex_item { padding: 5px 10px; }
Flexbox に関する考慮事項
以下は、「CSS flexible box の利用・flex アイテムで考慮すべき事柄 /developer.mozilla.org 」からの抜粋です。
-
Flex コンテナの直接の子要素になっているテキストは、無名の flex アイテムに包まれています。しかし、ホワイトスペースのみを含む無名の flex アイテムはレンダリングされません。これは、display: none が指定されたような状態です。
-
flex コンテナの子要素で絶対的に配置したものは、静的な位置が flex コンテナの main start 側の content-box の隅に対して決められるように配置されます。
-
隣接する flex アイテムのマージンは相殺しません。auto マージンを使用すると垂直方向または水平方向に追加のスペースを取り込みますので、flex アイテムの整列や分離に使用できます。
-
要素の表示順序はソースコードでの順序とは独立していますが、この独立性は視覚的なレンダリングにのみ影響しており、読み上げ順やソースでの順序に基づくナビゲーションには影響しないことを思い出しましょう。order プロパティも、読み上げやナビゲーションの順序に影響を与えません。よって、開発者はドキュメントのアクセシビリティを壊さないように、ソースコードで適切に要素を並べるように気をつけなければなりません。
Flexbox に影響を与えないプロパティ
以下の CSS プロパティは Flex コンテナでは効果がありません。(flexible box に影響を与えないプロパティ /developer.mozilla.org)
- マルチカラムモジュールの column-* プロパティは、flex アイテムに対する効果がありません。
- flex アイテムで、float および clear は効果がありません。float を使用すると、その要素の display プロパティは block であると算定されます。
- vertical-align は、flex アイテムの配置に影響を与えません。
Flexbox を使ったレイアウト
Flexbox を使ったレイアウトの例です。
均等配分 / flex: 1 1 auto
全てのフレックスアイテムに flex: 1 1 auto; を指定すると、水平方向の余分な領域を均等に配分することができます。フレックスアイテムのコンテンツの内容が同じであれば、等幅に分割されます。
<div class="flex_container_fill"> <div class="flex_item_fill">Flex item</div> <div class="flex_item_fill">Flex item</div> <div class="flex_item_fill">Flex item</div> </div>
.flex_container_fill { display: flex; flex-direction: row; max-width: 670px; } .flex_item_fill { flex: 1 1 auto; margin: 5px; padding: 5px; }
以下は2つ目のフレックスアイテムのコンテンツが長い場合の例で、余った領域を均等に配分します。
<div class="flex_container_fill"> <div class="flex_item_fill">Flex item</div> <div class="flex_item_fill">Flex item (Extra content)</div> <div class="flex_item_fill">Flex item</div> </div>
margin: auto 余白の自動調整
Flexbox と margin プロパティの値 auto を組み合わせると、自動的に余白の調整を行うことができます。但し、IE10 と IE11 では、親要素がデフォルト以外の justify-content の値を持つフレックスアイテムの margin: auto; を正しくサポートしていません。
以下は、margin-right: auto;と margin-left: auto;を利用して要素を配置(自動的に余白の調整を行う)する例です。
<div class="d-flex"> <div>Flex item</div> <div>Flex item</div> <div>Flex item</div> </div> <div class="d-flex"> <div style="margin-right: auto;">Flex item</div> <div>Flex item</div> <div>Flex item</div> </div> <div class="d-flex"> <div>Flex item</div> <div>Flex item</div> <div style="margin-left: auto;">Flex item</div> </div>
.d-flex { display: flex; }
align-items の flex-start または flex-end と flex-direction:column を margin-top: auto; または margin-bottom: auto; と組み合わせると垂直方向の余白を自動調整することができます。
<div class="d-flex-column-start" style="height: 160px;"> <div style="margin-bottom: auto;">Flex item</div> <div>Flex item</div> <div>Flex item</div> </div> <div class="d-flex-column-end" style="height: 160px;"> <div>Flex item</div> <div>Flex item</div> <div style="margin-top: auto;">Flex item</div> </div>
.d-flex-column-start { display: flex; flex-direction:column; align-items:flex-start } .d-flex-column-end { display: flex; flex-direction:column; align-items:flex-end; }
2カラムレイアウト
Flexbox を使ってメインコンテンツとサイドバーの領域を配置します。この例ではメインコンテンツの幅は伸縮させ、サイドバーの幅は固定にします(300px)。
レスポンシブ対応にするため、576px 未満では1カラムにし、576px 以上では2カラムのスタイルを適用させるようにしています。
576px 以上の場合、親要素の container クラスの div 要素に display: flex; を指定します。
メインコンテンツの領域には、flex プロパティを使って「flex: 1 1 auto;」を、サイドバーの領域には、「flex: 0 0 300px; 」を設定します。(flex-grow、flex-shrink、flex-basis の順で指定)
サイドバーの flex-shrink には 0 を指定してオリジナルサイズを維持させ、flex-basis にはサイドバーの幅を指定します。サイドバーにはパディング 2% を指定していますが、box-sizing: border-box; を指定しているので300pxに固定されます。
以下が HTML と CSS です。
<div class="container"> <section class="main"> <h1>Main</h1> <p> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Magnam totam....</p> </section> <section class="side"> <h2>Side</h2> <p>A, unde, voluptas, explicabo, est placeat molestias...</p> </section> </div>
* { margin:0; padding:0; box-sizing: border-box; } .container { margin: 40px auto 0; max-width: 1060px; position: relative; } .main { background: #BFF2F7; } .side { background: #FCE1E2; } .main, .side { padding: 2%; } /* Responsive */ @media ( min-width : 576px ){ .container { display: flex; } .main { margin: 0 10px 0 0; flex: 1 1 auot; } .side { flex: 0 0 300px; }
container の幅 = main の幅 + サイドバーの幅 + 10px (マージン)
サイドバーも伸縮させる場合
以下はサイドバーも伸縮させる場合の一例です(他にも方法はあると思います)。サイドバーの幅を 30%, メインの幅を calc() 関数を使って calc(70% - 10px) を指定しています。(10px はマージン分)
また、IE11 にはバグがあり flex ショートハンドで calc() 関数を利用できません。そのため、IE11をサポートするには、flex ショートハンドプロパティではなく、個々のプロパティを記述する必要があります。
前述の例との違いは、以下のメディアクエリの部分になります。
@media ( min-width : 576px ){ .container { display: flex; } .main { margin: 0 10px 0 0; flex-grow: 1; flex-shrink: 1; flex-basis: calc(70% - 10px); } .side { flex-grow: 1; flex-shrink: 1; flex-basis: 30%; } }
2カラムの左右を入れ替える
Flex アイテムの並び順は HTML を編集せずに order プロパティを使って簡単に変更することができます。
order プロパティは Flex アイテムの並び順を設定するプロパティで、値には整数を指定し、値が小さいほど先に配置されます。
order プロパティのデフォルトの値は 0 です。この例の場合は、サイドバーを先に表示させるようにするので、サイドバーに「 order : -1; 」を指定するだけで左右を入れ替えることができます。
また、左右が入れ替わるのでメインのマージンも変更します(左マージンから右マージンへ変更)。
HTML は変更する必要はありません。
@media ( min-width : 576px ){ .container { display: flex; } .main { margin: 0 0 0 10px; /* 変更 */ flex-grow: 1; flex-shrink: 1; flex-basis: calc(70% - 10px); } .side { flex-grow: 1; flex-shrink: 1; flex-basis: 30%; order: -1; /* 追加 */ } }
3カラムレイアウト
3カラムレイアウトの場合も基本的には2カラムとほぼ同じです。
Flexbox を使ってメインコンテンツと2つのサイドバーの領域を配置します。この例ではメインコンテンツの幅は伸縮させ、サイドバーの幅は固定にします(240px と 180px)。
また、レスポンシブ対応にするため、576px 未満では1カラムにし、576px 以上では3カラムのスタイルを適用させるようにしています。(実際にはブレークポイントはもっと大きな値を指定すると思いますが、以下のサンプルの幅が狭いため、2カラムのサンプル同様、576px にしています。)
576px 以上の場合、親要素の container クラスの div 要素に display: flex; を指定します。
メインコンテンツの領域には、flex プロパティを使って「flex: 1 1 auto;」を、サイドバーの領域には、「flex: 0 0 240px; 」、「flex: 0 0 180px; 」をそれぞれ設定します。(flex-grow、flex-shrink、flex-basis の順で指定)
<div class="container"> <section class="side1"> <h2>Side1</h2> <p>A, unde, voluptas, explicabo, est placeat molestias...</p> </section> <section class="main"> <h1>Main</h1> <p> Lorem ipsum dolor sit amet, consectetur adipisicing elit....</p> </section> <section class="side2"> <h2>Side2</h2> <p>Aut, dolores dolorem totam sunt consequuntur ipsam...</p> </section> </div>
* { margin: 0; padding: 0; box-sizing: border-box; } .container { margin: 40px auto 0; max-width: 1060px; position: relative; } .main, .side1, .side2 { padding: 2%; } @media ( min-width : 576px ) { .container { display: flex; } .main { margin: 0 10px 0; flex: 1 1 auto; } .side1 { flex: 0 0 240px; } .side2 { flex: 0 0 180px; } }
container の幅 = サイドバー1の幅 + main の幅 + サイドバー2の幅 + 20px (マージン)
サイドバーも伸縮させる場合(1)
サイドバーの幅をそれぞれ 25%, 20% とし、メインの幅を calc() 関数を使って calc(55% - 20px) を指定しています。(20px は左右マージン分)
また、IE11 にはバグがあり flex ショートハンドで calc() 関数を利用できません。そのため、IE11をサポートするには、flex ショートハンドプロパティではなく、個々のプロパティを記述する必要があります。
前述の例との違いは、以下のメディアクエリの部分になります。
@media ( min-width : 576px ) { .container { display: flex; } .main { margin: 0 10px 0; flex-grow: 1; flex-shrink: 1; flex-basis: calc(55% - 20px); } .side1 { flex-grow: 0; flex-shrink: 0; flex-basis: 25%; } .side2 { flex-grow: 0; flex-shrink: 0; flex-basis: 20%; } }
サイドバーも伸縮させる場合(2)
flex プロパティに値を1つ指定して、Flex アイテムの幅の割合を指定する例です。例えば「flex:1;」と指定した場合、「flex:1 1 0;」を指定したのと同じことになり、flex-basis が 0 で計算され、指定した割合でレイアウトされます。以下の例は、サイドバーにそれぞれ 1 を、メインに 2 を指定しています。
@media ( min-width : 576px ) { .container { display: flex; } .main { margin: 0 10px 0; flex:2; } .side1 { flex:1; } .side2 { flex:1; } }
上記は以下と同じことになります。
@media ( min-width : 576px ) { .container { display: flex; } .main { margin: 0 10px 0; flex-grow: 2; flex-shrink: 1; flex-basis: 0; } .side1 { flex-grow: 1; flex-shrink: 1; flex-basis: 0; } .side2 { flex-grow: 1; flex-shrink: 1; flex-basis: 0; } }
カラムの順番を入れ替える
Flex アイテムの並び順は HTML を編集せずに order プロパティを使って簡単に変更することができます。
order プロパティは Flex アイテムの並び順を設定するプロパティで、値には整数を指定し、値が小さいほど先に配置されます。
order プロパティのデフォルトの値は 0 です。それぞれのカラム(領域)に order プロパティで順序を指定します。
必要に応じてマージンの指定を変更します。
@media ( min-width : 576px ) { .container { display: flex; } .main { margin: 0 10px 0 0; flex:2; order:1; } .side1 { margin-right: 10px; flex:1; order:2; } .side2 { flex:1; order:3; } }
マルチカラムでのマージン
マルチカラムでマージンを設定する例です。各カラムにマージン(間隔・ガター)を設定したい場合は Flex アイテムに margin-left を設定し、 Flex コンテナに同じ値のネガティブマージンを設定します。
Flex アイテム(.col)が一行に収まっているのは、デフォルトの flex-shrink:1 が適用されて自動的に幅を調節して一行に収められているためです。
<div class="row"> <div class="col">col 1</div> <div class="col">col 2</div> <div class="col">col 3</div> </div> <div class="row"> <div class="col">col 1</div> <div class="col">col 2</div> <div class="col">col 3</div> <div class="col">col 4</div> </div> <div class="row"> <div class="col">col 1</div> <div class="col">col 2</div> <div class="col">col 3</div> <div class="col">col 4</div> <div class="col">col 5</div> </div>
.row { display: flex; margin-left: -20px; } .col { width: 100%; margin-left: 20px; height: 60px; }
ボックスを整列(タイル)
メインコンテンツにボックスを並べて表示するタイルレイアウトの一例です。
Flexbox を使用すると各ボックスの高さが異なっても、自動的に一番高いものに合わせて並べてくれるので便利です。
Flex コンテナに flex-wrap: wrap を指定して、折り返すように指定します(デフォルトでは1列に並べようとします)。
HTML のマークアップは各ボックス(Flex アイテム)を div 要素でマークアップしています。Flex コンテナは flex_container クラスを指定した div 要素です。(Flex コンテナに ul 要素、Flex アイテムに li 要素を使う方法などもあります)
この例では、各 Flex アイテムにマージンを指定せず、Flex コンテナに justify-content: space-around を指定して適切な間隔を設けるようにしています。各 Flex アイテムの幅を 24% として、横に4つ並べるようにしています。
この方法の場合、表示する数がちょうど4の倍数になっていれば問題ありませんが、そうでない場合は最後の行が4つ未満の場合、均等配置されてしまいます。そのため、この例では合計数が4の倍数にするため、空の div 要素を2つ挿入しています。
また、Flex コンテナ内部の要素の配置が伸縮するのかどうかなどによっても動作が変わってきます。(この例では img 要素を伸縮するように設定しています)
<div class="container"> <div class="flex_container"> <div class="flex_item"><h3>Flex Item 1</h3> <img src="http://via.placeholder.com/240x160" alt="" /> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p> </div> <div class="flex_item"><h3>Flex Item 2</h3> <img src="http://via.placeholder.com/240x160" alt="" /> <p>Magnam totam saepe provident cum suscipit explicabo architecto earum necessitatibus nam corporis?.</p> </div> ...中略... <div class="flex_item"><h3>Flex Item 10</h3> <img src="http://via.placeholder.com/240x160" alt="" /> <p>Fuga commodi qui maiores accusantium provident ullam magnam ipsam quos., consectetur adipiscing elit...</p> </div> <div class="flex_item"></div> <div class="flex_item"></div> </div> </div>
Flex コンテナには、「display: flex」「flex-wrap: wrap(折り返しの指定)」、「space-around(均等配置)」を指定します。
Flex アイテムには「flex: 0 0 24%」を指定して、基準幅を 24% として、横に4つ表示するようにしています。
また、空の div 要素(.flex_item:empty)にはボーダーや背景色を表示しないように設定しています。
* { margin: 0; padding: 0; box-sizing: border-box; } .container { margin: 10px auto 0; max-width: 1060px; position: relative; } .flex_item { margin-bottom: 10px; text-align: center; } .flex_item img { margin: 10px; width: 90%; max-width: 240px; } .flex_item:empty { border: none; background: none; } @media ( min-width : 576px ) { .flex_container { display: flex; flex-wrap: wrap; justify-content: space-around; } .flex_item { flex: 0 0 24%; } }
タイル2
以下の例は HTML マークアップは前述の例と(画像の幅以外)同じですが、Flex コンテナ内の画像要素を固定幅にした場合の例です。
Flex アイテムには「flex: 1 0 220px;」を指定(画像幅 200px, 左右マージン 20px)し、「flex-grow: 1」を設定して余白分広がるように設定しています。また、マージン(左右5px)も設定しています。
この例の場合は、余白分広がるように設定しているので justify-content は特に指定する必要はありません。
Flex アイテムに「flex: 1 0 24%;」と flex-basis を % で指定すると、IE11 では期待した動作をしません。また、その他のブラウザでも最後の行のレイアウトが異なってしまうため、空の div 要素に幅の指定をしなければならないなどうまく機能しません。
この場合、幅を狭めていくと列数が4列、3列、2列と変化していきます。
.flex_item img { margin: 10px; } @media ( min-width : 576px ) { .flex_container { display: flex; flex-wrap: wrap; /*justify-content: space-around;*/ } .flex_item { flex: 1 0 220px; /* flex-basis を px で指定 */ margin: 0 5px 10px; } }
ボックスを整列(2)
Flexbox を使ってボックスを横に並べ、ボックス自体も伸縮させる例です。また、この例では各ボックス内のリンクボタンの位置も、Flexbox で整列させます。
この例では2つの Flex コンテナーを使用しています。1つは flex_container クラスの div 要素で、その子要素の flex_item クラスの div 要素を横に並べています。
もう1つは、flex_item クラスの div 要素にも display: flex を指定して Flex コンテナーにしています。この要素には更に、flex-direction: column; を指定してその子要素の Flex アイテムが縦に並ぶようにしています。
1行に4つのボックスを並べるため、flex_item クラスの div 要素には flex: 0 0 24%; を指定しています。
レスポンシブ対応にするため、576px 未満では1カラムにしています。
<div class="flex_container"> <div class="flex_item"> <img src="http://via.placeholder.com/240x160" alt="" /> <h3>Flex Item 1</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p> <a href="#" class="button">Contact</a> </div> <div class="flex_item"> <img src="http://via.placeholder.com/240x160" alt="" /> <h3>Flex Item 2</h3> <p>Magnam totam saepe provident cum suscipit explicabo ......</p> <a href="#" class="button">Contact</a> </div> <div class="flex_item"> <img src="http://via.placeholder.com/240x160" alt="" /> <h3>Flex Item 3</h3> <p> Fuga commodi qui maiores accusantium provident ullam magnam .......</p> <a href="#" class="button">Contact</a> </div> <div class="flex_item"> <img src="http://via.placeholder.com/240x160" alt="" /> <h3>Flex Item 4</h3> <p>A, unde, voluptas, explicabo, est placeat molestias dignissimos ......</p> <a href="#" class="button">Contact</a> </div> </div> <div class="flex_container"> <div class="flex_item"> <img src="http://via.placeholder.com/240x160" alt="" /> <h3>Flex Item 5</h3> <p>nulla ipsa voluptatum laboriosam optio perspiciatis .......</p> <a href="#" class="button">Contact</a> </div> ・・・中略・・・ </div>
button クラスの a 要素は、flex_item クラスの子要素なので、Flex アイテムになります。この場合、Flex アイテムに margin-top: auto を指定すると、その要素の上マージンが自動的に調整されて配置されます。
* { margin: 0; padding: 0; box-sizing: border-box; } .button { margin: auto auto 10px; /* margin-top を auto に指定 */ padding: 5px 10px; display: block; width: 120px; } .container { margin: 40px auto 0; max-width: 1060px; position: relative; } .flex_item { margin-bottom: 10px; } .flex_item img { margin: 10px auto; width: 100%; max-width: 240px; } .flex_item:empty { border: none; background: none; } @media ( min-width : 576px ) { .flex_container { display: flex; justify-content: space-around; } .flex_item { flex: 0 0 24%; margin: 0 5px 10px; display: flex; /* 入れ子になった Flex コンテナ */ flex-direction: column; /* 子要素を縦に並べる */ } }
折り返して表示させる例
前述の例は、Flex コンテナの中に4つずつボックスを配置しましたが、以下は Flex コンテナの中にたくさんのボックスを配置して、折り返し表示させる例です。
この例も、幅が広い場合は横に4つ表示させますが、幅を狭めるとボックスの表示を3つ、2つと幅により変化します。
また、全てのボックスを同じ幅で表示するため、ボックスの合計が4の倍数になるように、最後に空の div 要素を追加しています。、空の div 要素(.flex_item:empty)にはボーダーや背景色を表示しないように設定しています。
flex_item クラスの div 要素には flex:1 0 240px; を指定(画像幅 240px)し、「flex-grow: 1」を設定して余白分広がるように設定しています。
<div class="flex_container"> <div class="flex_item"> <img src="http://via.placeholder.com/240x160" alt="" /> <h3>Flex Item 1</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p> <a href="#" class="button">Contact</a> </div> <div class="flex_item"> <img src="http://via.placeholder.com/240x160" alt="" /> <h3>Flex Item 2</h3> <p>Magnam totam saepe provident cum suscipit explicabo architecto.....</p> <a href="#" class="button">Contact</a> </div> <div class="flex_item"> <img src="http://via.placeholder.com/240x160" alt="" /> <h3>Flex Item 3</h3> <p> Fuga commodi qui maiores accusantium provident ullam magnam .....</p> <a href="#" class="button">Contact</a> </div> ・・・中略・・・ <div class="flex_item"> <img src="http://via.placeholder.com/240x160" alt="" /> <h3>Flex Item 10</h3> <p>Fuga commodi qui maiores accusantium provident ullam magnam ipsam quos.....</p> <a href="#" class="button">Contact</a> </div> <div class="flex_item"></div> <div class="flex_item"></div> </div>
* { margin: 0; padding: 0; box-sizing: border-box; } .button { display: block; width: 120px; margin: auto auto 10px; } .container { margin: 40px auto 0; max-width: 1060px; position: relative; } .flex_item { margin-bottom: 10px; } .flex_item img { margin: 10px auto; width: 100%; max-width: 240px; } .flex_item:empty { border: none; background: none; } @media ( min-width : 576px ) { .flex_container { display: flex; flex-wrap: wrap; /* 折り返し表示 */ justify-content: space-around; } .flex_item { flex:1 0 240px; margin: 0 5px 10px; display: flex; flex-direction: column; } }
上下左右の中央配置
Flexbox を使うと、上下左右の中央配置も簡単にできます。wrapper クラスの div 要素を Flex コンテナとして指定し、Flex アイテム(center クラスの div 要素)を主軸方向及(justify-content)び交差軸方向(align-items)に中央配置(center)するだけです。
<div class="wrapper"> <div class="center"> <p>Lorem ipsum dolor sit amet</p> </div> </div>
.wrapper { display: flex; justify-content: center; align-items: center; width: 300px; height: 300px; margin: 30px auto; border: 1px solid #ccc; } .center { border: 1px solid #999; background-color: #E2F7DF; padding: 20px; height: 100px; width: 100px; text-align: center; }
p 要素内のテキストは、「text-align: center」で水平方向に中央寄せしていますが、垂直方向にも中央配置するには、center クラスの div 要素に「display: flex;」を指定して Flex コンテナとして、「align-items: center;」を指定します。
.center { border: 1px solid #999; background-color: #E2F7DF; padding: 20px; height: 100px; width: 100px; text-align: center; display: flex; /* 追加 */ align-items: center; /* 追加 */ }
参考サイト