CSS Flexboxで作るレスポンシブなレイアウト
CSSのFlexboxで実装できるレスポンシブなレイアウトをまとめました。実際に Web サイトで使われるカラムレイアウトやカードレイアウ トを中心とした、レイアウトのサンプルとコードを紹介しています。以前は float などが使 用されることが多かった複数の要素を並行に並べるレイアウトも、Flexbox を使用することで簡単に 作成することができます。
Flexboxの基本的な使い方はこちらの記事でも紹介しています。
2カラムのレイアウト
複数の要素を並行に並べるカラムレイアウトを、Flexboxを使って以前はfloatなどが使用されることが多かったカラムレイアウトも、Flexboxを使用することで簡単に作成することができます。左側の横幅を固定して、右側の幅がウィンドウサイズに合わせて変化する2カラムのレイアウトです。
<div class="flex-sample">
<div class="item1">1</div>
<div class="item2">2</div>
</div>
.flex-sample {
display: flex;
width: auto;
}
.flex-sample .item1 {
flex: 0 0 300px;
}
.flex-sample .item2 {
flex: 1;
}
※Flexbox以外の、背景色、余白(margin)などの設定は割愛しています。
片方の横幅が可変する側の Flex アイテム(この例では ITEM2 の div)に「flex: 1;」を設定します。「flex: 1;」は、値を一つだけ設定した場合、flex-grow と同じ効果があり、Flex アイテムの横幅が伸びる設 定になります。
上記の例では、ITEM1 は「flex: 0 0 300px;」で横幅が固定され、ITEM2 のエリアが Flex コンテナの サイズに合わせて変動します。
左右交互のレイアウト
2カラムのレイアウトをFlexboxで作成した場合、例のような左右が交互に入れ替わるタイプのレイアウトも簡単に設定できます。
<div class="flex-sample">
<div class="item1">1</div>
<div class="item2">2</div>
</div>
<div class="flex-sample">
<div class="item1">1</div>
<div class="item2">2</div>
</div>
<div class="flex-sample">
<div class="item1">1</div>
<div class="item2">2</div>
</div>
.flex-sample {
display: flex;
width: auto;
}
.flex-sample:nth-child(even) {
flex-direction: row-reverse;
}
.flex-sample .item1 {
flex: 0 0 300px;
}
.flex-sample .item2 {
flex: 1;
}
.flex-sample:nth-child(even)
で偶数番目のFlexコンテンツに、flex-direction: row-reverse;
を設定しています。row-reverseを設定すると、Flexアイテムの順序が逆並びになります。
この方法であれば、div要素の順番を変えずに左右の並びを変更することができます。
3カラムのレイアウト
3つの要素が並ぶレイアウトの作成例です。
<div class="flex-sample">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
.flex-sample {
display: flex;
}
.flex-sample .item {
flex: 1;
}
Flexboxを設定するだけで、デフォルトで横並びになるので、Flexアイテムにflex: 1;
を設定して横幅を均等になるように指定するだけで、キレイな3カラムのレイアウトが作成できます。
レスポンシブでレイアウトを変更する必要がある場合は、コードを1行書き換えるだけで縦並びに変更できます。
.flex-sample {
display: flex;
flex-direction: column;
}
.flex-sample .item {
flex: 1;
}
flex-direction: column;
を設定すると、FLexアイテムを縦並びにすることができます。
一部のFlexアイテムのみ横幅を可変にしたい場合は、ウィンドウサイズに合わせて個別に変動するようにflex: 1;を設定します。
<div class="flex-sample">
<div class="item1">1</div>
<div class="item2">2</div>
<div class="item3">3</div>
</div>
.flex-sample {
display: flex;
}
.flex-sample .item1 {
flex: 0 0 300px;
}
.flex-sample .item2 {
flex: 1;
}
.flex-sample .item3 {
flex: 0 0 250px;
}
2カラムと同様に、変動する Flex アイテムに「flex: 1;」を、残りの Flex アイテムに固定の幅を設定 します。上記のサンプルでは、中央の Flex アイテムのみ横幅に合わせて変動するようになりました。
4カラムのレイアウト
4カラムのレイアウトも、3カラムと同様です。
<div class="flex-sample">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
.flex-sample {
display: flex;
}
.flex-sample .item {
flex: 1;
}
flex: 1;で横幅を統一したレイアウトです。横幅は全ての Flex アイテムで統一されます。中身のコ ンテンツの量に応じて Flex アイテムの高さは変動します。デフォルトの設定では、全ての高さは一 番大きい Flex アイテムに統一されます。
Flexアイテムの間に余白のあるレイアウトについては、後述のカードレイアウトをご参照ください。
カラムの変動するレイアウト
Flexコンテナの横幅に合わせてカラムの数が切り替わるレイアウトです。
<div class="flex-sample">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
</div>
.flex-sample {
display: flex;
flex-wrap: wrap;
}
.flex-sample .item {
flex: 1 0 300px;
}
Flexboxで作成したレイアウトでは、Flexアイテムの横幅の合計がFlexコンテナの幅を超えても横並びのまま連なります。そのため、Flexコンテナにflex-wrap: wrap;
を指定して、幅がオーバーした分のFlexアイテムを改行する必要があります。
次に、flex: 1 0 300px
を指定することで、横幅が300px以下にならず、Flexコンテナに合わせて幅が伸びるFlexアイテムを設定しています。
flexには、flex-grow、flex-shrink、flex-basisの値を順に指定することができます。
flex: [flex-grow] [flex-shrink] [flex-basis];
1つ目の値で、flex-growに1を指定することで、Flexコンテナの横幅に合わせFlexアイテムの幅が均等に伸びるように設定しています。2つ目の値では、flex-shrinkに0を指定して、flexアイテムが基準値(flex-basisで設定した値)より縮まないように設定しています。3つ目の値では、flex-basisでFlexアイテムの基準となる幅を300pxに指定しています。
つまり、Flexアイテムの横幅は最小で300pxとなり、Flexコンテナの横幅に合わせて折り返すレイアウトになります。
カードレイアウト
Flexアイテムに余白を持たせて均等に並べたカードレイアウトです。
Flexboxで作成したレイアウトでは横幅や余白が自動で設定されるため、レスポンシブを考慮したカードレイアウトの作成も可能です。
<div class="flex-sample">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
.flex-sample {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.flex-sample .item {
flex: 0 0 30%;
margin: 40px 0 0;
}
※カード部分の、HTMLとCSSの設定は割愛しています。
上記の例では、で一つのFlexアイテムの横幅をFlexコンテナ横幅の30%に設定し、3枚ずつカードが並ぶレイアウトにしました。縦の長さはデフォルトで行毎に統一されます。Flexコンテナの横幅とFlexアイテムの幅の合計の差が、そのまま余白になります。この時、justify-content: space-between;
を指定することで、余白が均等に配分されるように設定しています。
カードの枚数が揃わない場合の設定
上記の例では、カードが5枚の時に2段目のカードが中央を基準に配置されてしまいます。
このように、justify-contentを使った横幅の指定だけで余白作るレイアウトには、カードの上下の並びが綺麗に揃わないデメリットがあります。左寄せのカードレイアウトにするためには、個別に余白を設定する対策が必要です。
<div class="flex-sample">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
.flex-sample {
display: flex;
flex-wrap: wrap;
width: 980px;
}
.flex-sample .item {
flex: 0 0 300px;
margin: 50px 40px 0 0;
}
.flex-sample .item:nth-child(3n) {
margin-right: 0;
}
例では、:nth-child(3n)
で3の倍数番目(右側にくるカード)のFlexアイテムのみ右側の余白を指定せず、Flexコンテナの横幅と、Flexアイテムの幅と余白の合計をpxで揃えて指定することで、カードを左揃えに並べています。
この方法であれば、横幅や余白が変動しない縦横がきっちりと揃ったレイアウトを作成することが可能です。
高さの変動するレイアウト
Flexアイテムの高さは、デフォルトでは統一されています。align-items: flex-start;
を設定することで、各Flexアイテム毎の高さに変更が可能です。
<div class="flex-sample">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
.flex-sample {
display: flex;
align-items: center;
height: 100%;
}
.flex-sample .item {
flex: 1;
}
.flex-sample .item:nth-child(2) {
align-self: stretch;
}
上記の例では、Flexコンテナの高さにheight: 100%;を設定し、align-items: center;でFlexアイテムがそれぞれの高さで中央揃えになるように配置しています。
そして、:nth-child(2)を指定して2番目のFlexアイテムにalign-self: stretch;
を設定することで、個別に高さがFlexコンテナいっぱいになります。align-selfは、Flexアイテムに直接設定できるプロパティで親要素に指定するalign-itemsより優先して高さと配置を指定できます。
中央揃えのレイアウト
positionなどを使用するより簡単に、左右上下中央に配置することができます。
<div class="flex-sample">
<div class="item">1</div>
</div>
.flex-sample {
display: flex;
justify-content: center;
align-items: center;
}
justify-content: center;
で Flex アイテムを水平方向の中央に、align-items: center;
で上下中央 に配置しています。
CSSで中央配置を実装するには、positionやmarginなどを使用した方法もありますが、Flexboxでは数行で、横幅や余白の計算も必要なく簡単に実装できます。
Flexbox の登場で、より柔軟なレイアウトの作成 が可能になりました。