flexboxを使い始めたけど、いまいち思った通りのレイアウトに実装できない…
そもそもどんなことが出来るの?
そんな方は必読です!
Flexboxのプロパティをひとつずつ見ると実はそこまで難しいことではないのですが、プロパティが多すぎて慣れるまでに時間がかかってしまいますよね。
この記事ではFlexboxの基本の使い方から、全プロパティの解説、Flexboxを使った作例もご紹介します!
この記事を読んで基礎をしっかり抑えたら、実際に手を動かしてFlexboxを使っていくつかコーディングをしてみてください。
一層理解が深まること間違いなしです!
Flexboxとは?
FlexboxとはCSS3から導入されたレイアウトモジュールのことで、正式名称をFlexible Box Layout Moduleといいます。
Flexboxを説明する際、「横方向・縦方向に要素を並べるプロパティ」と解説される場合もありますが、正確にはちょっと異なります。
Flexboxは指定されてる軸方向に要素を並べるプロパティです。
具体的には、親要素=フレックスコンテナの中で、flex-directionの値として適用されている軸方向に対し、水平方向か垂直方向に子要素=フレックスアイテムを配置するプロパティということになります。
この考えをしっかり認識しておけば、Flexboxはもう怖くありません。
これまでfloatなどを駆使して作った複雑なレイアウトも、Flexboxを使えば比較的簡単に作成できてしまいます。
基本的な使い方
要素にdisplay: flex;を指定することで、その要素はflexコンテナとなり、直下にある子要素は自動的にflexアイテムとなります。
<div class="flex-container">
<div class="flex-item">item1</div>
<div class="flex-item">item2</div>
<div class="flex-item">item3</div>
</div>
.flex-container {
display: flex;
}
これだけで、flexアイテム化した子要素のレイアウトを制御できるようになります。
上の画像のように、コンテナの中でflexアイテム化した子要素が自動的に整列します。軸方向を指定していない初期値の状態では、コンテナに対して水平方向(横方向)に子要素が並びます。
ちなみに、flexアイテム化するのは、display: flex;を指定した要素の直下にある子要素のみです。
<div class="flex-container">
<div class="flex-item"> <!-- flexアイテム01 -->
<ul>
<li>item01</li>
<li>item02</li>
<li>item03</li>
</ul>
</div>
<div class="flex-item"> <!-- flexアイテム02 -->
<ul>
<li>item01</li>
<li>item02</li>
<li>item03</li>
</ul>
</div>
</div>
上の例だとflex-itemクラスがついたdivタグはflexアイテム化しますが、ulタグ以下の階層は、flexコンテナの直下にはならないため、Flexboxを使った直接的なレイアウト指定はできません。
また、Flexboxを使った実際のコーディング動画はYouTubeでも解説しているので要チェックです!
Flexbox以外の並列レイアウト方法とその違い
Flexbox以外には、次のような並列レイアウト方法があります。
今回は詳しい解説は省きますが、レイアウトのための横並びであればFlexboxを使っておけば基本的に問題はないと覚えておくと良いでしょう。
レイアウト方法 | 解説 |
---|---|
float: left (もしくはright) | 要素を回り込ませることで横並びにする |
display: inline-block | inline化させて左詰に横並びにする |
display: table | 要素をテーブル化して横並びにする |
親要素(flexコンテナ)に指定するプロパティ
flexコンテナに指定するプロパティは次の通りです。
プロパティ | 効果 |
---|---|
flex-direction | アイテムが並ぶ方向(水平方向か垂直方向)を決める |
justify-content | アイテムの配置方法を決める |
align-items | flex-directionの軸方向に対して、垂直にアイテム配置方法を決める |
flex-wrap | コンテナ内でアイテムを折り返すかどうかと、折り返し方を決める |
align-content | 複数行にわたるアイテムが、垂直方向にどう配置されるかを決める |
それでは詳細を見ていきましょう。
flex-direction
アイテムが並ぶ方向(水平方向か垂直方向)を決めるプロパティです。
このプロパティの値が、他のすべてのプロパティにも影響を与えます。
値 | 結果 |
---|---|
row | (初期値)コンテナ先頭から水平方向に並べて配置 |
row-reverse | コンテナ末尾から水平方向に並べて配置 |
column | コンテナ先頭から垂直方向に並べて配置 |
column-reverse | コンテナ末尾から垂直方向に並べて配置 |
row
.flex-container {
flex-direction: row; /* 初期値なので記載しなくても適用される */
}
コンテナの先頭位置から水平方向に並べて配置していきます。
row-reverse
.flex-container {
flex-direction: row-reverse;
}
コンテナ末尾から水平方向に並べて配置していきます。
column
.flex-container {
flex-direction: column;
}
コンテナ先頭から垂直方向に並べて配置していきます。
column-reverse
.flex-container {
flex-direction: column-reverse;
}
コンテナ末尾から垂直方向に並べて配置していきます。
justify-content
flex-directionの軸方向に対して、水平方向のアイテム配置を決めるプロパティです。
値 | 結果 |
---|---|
flex-start | (初期値)先頭にアイテムを寄せる |
flex-end | 末尾にアイテムを寄せる |
center | 中央にアイテムを寄せる |
space-between | 最初と最後のアイテムを両端に配置し、それ以外は均等に配置 |
space-evenly | 両端・アイテム間すべてのスペースを同じに、各アイテムを均等配置 |
space-around | 両端にアイテム間半分のスペースを確保し、各アイテムを均等配置 |
※画像の例は、flex-direction未指定(初期値=横方向)時のスタイルです。
flex-start
.flex-container {
justify-content: flex-start; /* 初期値なので記載しなくても適用される */
}
コンテナ先頭にアイテムを寄せます。
flex-end
.flex-container {
justify-content: flex-end;
}
コンテナ末尾にアイテムを寄せます。
center
.flex-container {
justify-content: center;
}
コンテナ中央にアイテムを寄せます。
space-between
.flex-container {
justify-content: space-between;
}
最初と最後のアイテムをコンテナ両端に配置し、それ以外は均等に配置します。
space-evenly
.flex-container {
justify-content: space-evenly;
}
両端・アイテム間すべてのスペースを同じに、各アイテムを均等配置します。
space-around
.flex-container {
justify-content: space-around;
}
コンテナ両端にアイテム間半分のスペースを確保し、各アイテムを均等配置します。
align-items
flex-directionの軸方向に対して、垂直方向のアイテム配置を決めるプロパティです。
値 | 結果 |
---|---|
stretch | (初期値)flex-directionの軸に対して、コンテナ領域の垂直方向に要素を広げる |
flex-start | flex-directionの軸に対して、垂直方向に先頭からアイテムを寄せる |
flex-end | flex-directionの軸に対して、垂直方向に末尾からアイテムを寄せる |
center | flex-directionの軸に対して、垂直方向の中央にアイテムを寄せる |
baseline | flex-directionの軸に対して、各アイテムのベースラインに揃える |
わかりやすく、3つの異なる長さの文章を並べて解説します。
※画像の例は、flex-direction未指定(初期値=横方向)時のスタイルです。
stretch
.flex-container {
align-items: stretch; /* 初期値なので記載しなくても適用される */
}
flex-directionの軸に対して、コンテナ領域の垂直方向に要素を広げます。
ここが初期値であることがFlexboxの便利な特徴の一つでもありますが、子要素のコンテンツ高さが不揃いであっても、flexアイテム化した要素は自動的に親要素(flexコンテナ)幅に広がるため、子要素一つ一つに対して大きさの指定をする必要もなくなります。
flex-start
.flex-container {
align-items: flex-start;
}
flex-directionの軸に対して、垂直方向に先頭からアイテムを寄せます。
flex-end
.flex-container {
align-items: flex-end;
}
flex-directionの軸に対して、垂直方向に末尾からアイテムを寄せます。
center
.flex-container {
align-items: center;
}
flex-directionの軸に対して、垂直方向の中央にアイテムを寄せます。
baseline
.flex-container {
align-items: baseline;
}
flex-directionの軸に対して、各アイテムのベースラインに揃えます。
flex-wrap
コンテナ内でアイテムを折り返すかどうかと、折り返し方を決めるプロパティです。
すべてのアイテム幅の合計が、コンテナ幅を超えている時に適用されます。
値 | 結果 |
---|---|
nowrap | (初期値)アイテム幅を縮小させて、軸方向にすべてのアイテムをおさめる |
wrap | アイテム幅を縮小させずに、アイテムが複数行に折り返す |
wrap-reverse | アイテム幅を縮小させずに、末軸から先頭軸に向かって折り返す |
※画像の例は、flex-direction未指定(初期値=横方向)時のスタイルです。
nowrap
.flex-container {
flex-wrap: nowrap; /* 初期値なので記載しなくても適用される */
}
アイテム幅を縮小させて、軸方向にすべてのアイテムをおさめます。
flex-wrapを指定しない場合(=この初期値が適用する)、要素のコンテンツが持っている本来の大きさを無視し、強制的に要素を一方向に並べるため、コンテンツが潰れるような見た目になることもあります。
wrap
.flex-container {
flex-wrap: wrap;
}
アイテム幅を縮小させずに、アイテムが複数行に折り返します。
wrap-reverse
.flex-container {
flex-wrap: wrap-reverse;
}
アイテム幅を縮小させずに、末軸から先頭軸に向かって折り返します。
align-content
複数行にわたるアイテムが、垂直方向にどう配置されるかを決めるプロパティです。
flex-wrapでwrap、もしくはwrap-reverseが適応されている場合(子要素が折り返されて複数行にまたがる場合)にのみ適用されます。
値 | 結果 |
---|---|
stretch | (初期値)flex-directionの軸に対して、垂直方向に各アイテムを広げながら折り返す |
flex-start | 先頭から折り返しながらアイテムを並べる |
flex-end | 最後のアイテムが末軸に揃う(下揃え)ように折り返しながらアイテムを並べる |
center | flex-directionの軸に対して、中央位置を基準に折り返しながらアイテムを並べる |
space-between | flex-directionの軸に対して、最初と最後のアイテムを両端に配置、それ以外は均等に折り返しながら配置 |
space-around | flex-directionの軸に対して、両端にアイテム間半分のスペースを確保し、各アイテムを均等に折り返しながら配置 |
※画像の例は、flex-direction未指定(初期値=横方向)時のスタイルです。
stretch
.flex-container {
align-content: stretch; /* 初期値なので記載しなくても適用される */
}
flex-directionの軸に対して、垂直方向に各アイテムを広げながら折り返します。
flex-start
.flex-container {
align-content: flex-start;
}
先頭から折り返しながらアイテムを並べます。
flex-end
.flex-container {
align-content: flex-end;
}
最後のアイテムが末軸に揃う(下揃え)ように折り返しながらアイテムを並べます。
center
.flex-container {
align-content: center;
}
flex-directionの軸に対して、中央位置を基準に折り返しながらアイテムを並べます。
space-between
.flex-container {
align-content: space-between;
}
flex-directionの軸に対して、最初と最後のアイテムを両端に配置、それ以外は均等に折り返しながら配置します。
space-around
.flex-container {
align-content: space-around;
}
flex-directionの軸に対して、両端にアイテム間半分のスペースを確保し、各アイテムを均等に折り返しながら配置します。
flex-flow
「flex-direction」と「flex-wrap」をまとめて指定できるプロパティです。
指定する際は次のように記述します。flex-directionの値とflex-wrapの値の間にはスペースが必要です。
.flex-container {
flex-flow: [flex-directionの値] [flex-wrapの値];
}
使用例はこちら。
.flex-container {
flex-flow: row-reverse wrap;
}
gap
gapプロパティは要素間の余白を指定できるプロパティです。
/* 行方向の余白サイズ 列方向の余白サイズ */
gap: 30px 50px;
/* 下と同じ */
row-gap: 30px;
column-gap: 50px;
gapプロパティはrow-gap(行方向)やcolumn-gap(列方向)のショートハンドで、ひとつ目が行方向(縦)でふたつ目が列方向(横)の値です。
それぞれは半角スペースで区切って指定します。
コンテナ内の「要素が隣り合った要素間」のみに余白を設けるため、要素が隣り合っていないコンテナラインにgapは適用されません。
詳しくはこちらの記事で解説しているので、あわせてご覧ください。
子要素(フレックスアイテム)に指定するプロパティ
フレックスアイテムに指定できるプロパティは次の通り。
プロパティ | 効果 |
---|---|
order | アイテムを任意の順番に並べ替える |
align-self | flex-directionの軸方向に対して、垂直に子要素のアイテム配置を決める |
flexプロパティ | アイテムの長さや伸縮割合を指定する |
※画像の例は、flex-direction未指定(初期値=横方向)時のスタイルです。
order
<div class="flex-container">
<div class="flex-item item1">item1</div>
<div class="flex-item item2">item2</div>
<div class="flex-item item3">item3</div>
</div>
.item1 {
order: 0; /* 初期値なので記載しなくても適用される */
}
.item2 {
order: -1;
}
.item3 {
order: 2;
}
HTMLに記述したアイテムの並びを無視して、並び順を指定することができるプロパティです。
初期値は0で、数字の小さい順に並びます。マイナスの値を指定することもできます。
align-self
flex-directionの軸方向に対して、垂直に子要素のアイテム配置を決めるプロパティです。
親要素に適用されてる「align-items」の値を上書きします。
値 | 結果 |
---|---|
auto | (初期値)親要素で適用されてるalign-itemsを継承 |
flex-start | flex-directionの軸に対して、垂直方向の先頭位置にアイテムを寄せる |
flex-end | flex-directionの軸に対して、垂直方向の末尾位置にアイテムを寄せる |
center | flex-directionの軸に対して、垂直方向の中央位置にアイテムを寄せる |
baseline | flex-directionの軸に対して、他アイテムのベースラインに揃える |
stretch | flex-directionの軸に対して、コンテナ領域の垂直方向に要素を広げる |
ここでは2つめのアイテムに対して指定してみましょう。
※画像の例は、flex-direction未指定(初期値=横方向)時のスタイルです。
※親要素(フレックスコンテナ)のalign-items初期値はstretchのため、1つ目と3つ目のアイテムはコンテナ領域いっぱいに広がっています。
auto
.flex-container {
align-items: stretch;
}
.item2 {
align-self: auto; /* 初期値なので記載しなくても適用される */
}
親要素で適用されてるalign-itemsを継承します。
flex-start
.item2 {
align-self: flex-start;
}
flex-directionの軸に対して、垂直方向に先頭位置にアイテムを寄せます。
flex-end
.item2 {
align-self: flex-end;
}
flex-directionの軸に対して、垂直方向に末尾位置にアイテムを寄せます。
center
.item2 {
align-self: center;
}
flex-directionの軸に対して、垂直方向の中央位置にアイテムを寄せます。
baselne
.item2 {
align-self: center;
}
flex-directionの軸に対して、他アイテムのベースラインに揃えます。
stretch
.item2 {
align-self: stretch;
}
flex-directionの軸に対して、コンテナ領域の垂直方向に要素を広げます。
flexプロパティ
フレックスアイテムの長さや伸縮割合を指定できるプロパティです。
flex: 1 0 0; といったように、次の順番で3つのプロパティをまとめて指定できます。
- flex-grow(伸長値)
- flex-shrink(圧縮値)
- flex-basis(長さ)
.item3 {
flex: 1 0 0;
/*
flex-grow: 1;
flex-shrink: 0;
flex-basis: 0;
*/
}
flexプロパティは扱いが少々ややこしいので、別記事で詳しく解説しています。是非こちらもご覧ください!
FlexBoxで知っておきたいこと
flex-basisとwidthの使い分け方について
flex-basisは要素の長さを指定するためのプロパティです。
長さの指定と聞くと「width」でいいのでは?となる方もいると思いますが、正確には軸方向に対しての長さに効くプロパティなんです。
そのため、flex-directionがcolumnまたはcolumn-reverseの場合、flex-basisの値は高さの指定になります。
また、フレックスアイテム化している要素に、flex-basisとwidth(height)が同時に指定されている場合、flex-basisの値が優先適用されるので注意しましょう。
flex-basisはflexプロパティでまとめて指定ができるので、状況に応じて使い分けると良いでしょう。
「float」「clear」「vertical-align」はflexアイテムに影響を与えない
flexアイテムにたいして「float」「clear」「vertical-align」などの横並びの指定をしても、FlexBoxの指定が上書きするため効きません。
floatが効かない場合、親要素にdisplay: flexが指定されてないか確認してみましょう。
上でも説明しましたが、単純な横並びレイアウトのためであれば、FlexBoxの指定だけでも十分なケースが多いですが一応覚えておいたほうがいいルールです。
実際にFlexboxでデザインを作成してみる
それでは実際に、Flexboxを使った事例を見てみましょう。
今回は当ブログで配布しているコーディング課題初級編の一部を、FlexBoxを使って実装してみます。
こちらの記事からデザインをダウンロードできるので、読みながら一緒にやってみてください!
※当記事と課題の解説記事で紹介しているコードには若干異なる部分がありますが、きちんとデザインが再現できていれば問題ありません。
コーディングに正解はないので、一つのパターンとして参考にしてみてください!
コード全体とブラウザの表示はこちら。この後解説していきます。
<div class="container">
<div class="flex-container">
<div class="flex-item dummy-image"></div>
<div class="flex-item text-block">
<div>
<p class="bg-text">リリース時のサポートで<br>サービスのブランディング</p>
<p class="sm-text">弊社では、リリース時もサポートさせて頂きます。プレスリリース用のサイトや動画制作を通して、サービスのブランディングを行わせて頂きます。</p>
</div>
</div>
</div>
<div class="flex-container row-reverse">
<div class="flex-item dummy-image"></div>
<div class="flex-item text-block">
<div>
<p class="bg-text">リリース後のサポートで<br>効果を最大化させる</p>
<p class="sm-text">弊社では、リリース後もサポートさせて頂きます。サービスはリリース後に様々な課題にぶつかります。そこでクライアント様と一緒に改善を行うことで、デザインの効果を最大化させます。</p>
</div>
</div>
</div>
</div>
/* 太文字設定 */
.bg-text {
font-size: 24px;
letter-spacing: .1em;
}
/* 画像ダミー */
.dummy-image {
background-color: #c1c1c1;
height: 240px;
}
/* 全体コンテナ */
.container {
margin: 50px auto;
max-width: 1030px;
}
/********************
ここからFlexBoxの指定
********************/
/* フレックスコンテナ */
.flex-container {
display: flex;
justify-content: space-between;
}
/* フレックスアイテム */
.flex-item {
flex-basis: 480px;
}
.text-block {
align-items: center;
display: flex;
}
/* 折り返し(ヘルパークラス) */
.row-reverse {
flex-direction: row-reverse;
}
一行ずつflex-containerで囲い、画像とテキストをflexアイテム化
上の図のように一行ずつflex-containerというクラス名で囲みます。
画像とテキストは、それぞれflex-itemで囲んでおきましょう。
<div class="container">
<div class="flex-container">
<div class="flex-item dummy-image"></div>
<div class="flex-item text-block">
<p class="bg-text">省略</p>
<p class="sm-text">省略</p>
</div>
</div>
<div class="flex-container">
<div class="flex-item dummy-image"></div>
<div class="flex-item text-block">
<p class="bg-text">省略</p>
<p class="sm-text">省略</p>
</div>
</div>
</div>
/* 全体コンテナ */
.container {
max-width: 1030px;
}
/* フレックスコンテナ */
.flex-container {
display: flex;
justify-content: space-between;
}
/* フレックスアイテム */
.flex-item {
flex-basis: 480px;
}
flex-containerにdisplay: flex;の指定をしたことで、その子要素であるflex-itemがアイテム化されました。
アイテムの配置方法はspace-betweenとし、両端に揃うようにしています。
また、flex-basisを使ってアイテムの横幅を480pxと指定しました。
アイテムの高さ方向は、align-itemsの初期値であるstretchが適用されているので、コンテナの高さいっぱいに自動で引き伸ばしてくれています。
ブラウザ表示はこのようになります。
テキストのブロックを空divで囲み上下中央に配置
テキスト部分をコンテナの上下中央に配置させます。
<div class="flex-container">
<div class="flex-item dummy-image"></div>
<div class="flex-item text-block">
<div>
<p class="bg-text">省略</p>
<p class="sm-text">省略</p>
</div>
</div>
</div>
.text-block {
display: flex;
align-items: center;
}
ここでは、display: flexを使った上下中央寄せのテクニックを紹介します。
まず、2つのpタグをひとつのブロックとしてフレックスアイテム化させるため、空のdivタグで囲みまとめます。
囲んだら親要素にあたるtext-blockクラスにdisplay: flex;を指定します。(この時点で直下にある空のdivタグがフレックスアイテム化しました)
同時にalign-items: center;を指定することで、空のdivタグでひとまとめになった要素が、上下方向の中央に配置されます。
ここまでで次のように表示されます。
2段目の画像とテキストの並び順を変える
最後に、2段目のアイテムの順番を入れ替えます。
<div class="container">
<div class="flex-container">
省略
</div>
<div class="flex-container row-reverse">
省略
</div>
</div>
/* 折り返し(ヘルパークラス) */
.row-reverse {
flex-direction: row-reverse;
}
HTMLの2つ目のflex-containerに、row-reverseというヘルパークラスを追加しました。
追加したクラスに対し、flex-direction: row-reverse;の指定をすれば、直下のフレックスアイテムは末尾から順に並ぶため、テキストと画像の要素が一段目と逆方向に配置されます。
実際にはマージンなど少しいじって整える必要がありますが、レイアウトはこんな感じで概ね完成です!
まとめ
Flexboxの基礎や全プロパティの解説をご紹介しました。
慣れるまでがなかなか難しいですが、使いこなせればとても便利なFlexbox。
ぜひたくさん練習して身に付けましょう!!
コーディング課題初級編はバッチリだよって人は、中級編にも挑戦してみてくださいね!