Menu

CSS flexbox (display: flex) の使い方: 軸、配置、flex

flexbox は要素を横か縦に並べ、スペースの分け方と揃え方を制御します。display: flex、主軸と交差軸、コンテナのすべてのプロパティ、flex-grow、flex-shrink、flex-basis を、各アイテムの位置を実測するプレイグラウンドで解説します。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

display: flex の役割

親に display: flex を指定すると、直接の子要素が横一列に並び、同じ高さに引き伸ばされます。要素を横に並べるための float、inline-block、ほとんどの位置指定のテクニックが、この 1 つの宣言で置き換わります。

1 つ目のボックスでは、それぞれの div が 1 行を占めます。2 つ目では 3 つのアイテムが 1 行に並び、それぞれ内容の幅しかなく、One と Three は Two の高さまで引き伸ばされます。変えたのは親だけです。display: flex は コンテナ に書き、アイテムには書きません。

flexbox プレイグラウンド

値を選んで、アイテムが動くのを見てください。ボックスの下のコード行が見えている状態の CSS で、その下のリストは、ブラウザが実際に各アイテムを置いた位置を getBoundingClientRect() で測ったものです。

試してみること:

  • justify-content: space-between: アイテム 1 は x 0 に置かれ、アイテム 3 は反対側の端に接します。
  • align-items: center: 3 つのアイテムはそれぞれの高さを保ち、中心がそろいます。初期値の stretch では、アイテム 1 には自分の高さがないので、コンテナの 170px いっぱいに広がります。
  • flex-direction: column: 今度は justify-content がアイテムを 縦方向 に、align-items が横方向に動かします。2 つのプロパティは画面ではなく軸に従います。

主軸と交差軸

flex コンテナにはすべて 2 つの軸があります。主軸 はアイテムが並ぶ方向で、flex-direction で決まります。交差軸 はそれと直角に交わります。

flex-direction主軸交差軸justify-content の動かす方向align-items の動かす方向
row (初期値)横、読む順縦横縦
row-reverse横、逆順縦横縦
column縦、上から下横縦横
column-reverse縦、下から上横縦横

右から左のページ (dir="rtl") では、主軸が書字方向に従うので、row は右端から始まります。

コンテナのプロパティ

これらは display: flex の要素に書きます:

プロパティ役割初期値
flex-direction横か縦か、どちら向きかrow
flex-wrap場所が足りないときにアイテムを次の行に送るかnowrap
flex-flowflex-direction と flex-wrap のショートハンドrow nowrap
justify-content主軸に沿った配置と間隔normal (flex-start として動作)
align-items交差軸に沿ったアイテムの配置normal (stretch として動作)
align-contentアイテムが折り返したときの行と行の間隔normal
gapアイテムの間のすき間 (row-gap、column-gap)0

justify-content と align-items のすべての値は、専用のページで解説しています: justify-content と align-items。折り返しと方向は flex-wrap のページ にあります。

アイテムのプロパティ: flex-grow、flex-shrink、flex-basis

これらは子要素に書き、コンテナの幅の分け方を決めます:

  • flex-basis: 空きスペースを分ける前の、アイテムの出発点のサイズ (auto は「自分の width か内容を使う」という意味)。
  • flex-grow: 残った スペースを何単位分もらうか。0 なら伸びません。
  • flex-shrink: スペースが足りないときにどれだけ譲るか。0 なら縮みません。

flex のショートハンドで 3 つをまとめて指定します:

書き方意味動き
flex: initial (初期値)0 1 auto内容のサイズ。縮むことはあるが伸びない
flex: 11 1 0%0 から始まり、スペースを均等に分ける
flex: auto1 1 auto内容のサイズに、残りのスペースの分け前を足す
flex: none0 0 auto内容か width ちょうど。伸びも縮みもしない
flex: 22 1 0%flex: 1 のアイテムの 2 倍の分け前

どの行も padding の内側が幅 480px で、8px のすき間 2 つを引くと、アイテムに使えるのは 464px です。表示された幅で分け方がわかります。1 行目はそれぞれ約 155px、2 行目は 116 + 232 + 116 (flex: 2 のアイテムは隣のそれぞれの 2 倍の分け前)、3 行目は 100 + 372 で、flex: none のアイテムは幅を保ち、もう一方が残りをすべて取ります。

flexbox で作る実際のレイアウト

最初にロゴ、最後にリンクを置くヘッダーは、一番よくある flex のレイアウトです。1 つのアイテムに margin-inline-start: auto を付けると、その前の空きスペースをすべて使い、そのアイテムと後に続くものを最後まで押し出します:

align-items: center で大きいロゴの文字とリンクの高さがそろい、gap を使えば最後のリンクの margin を打ち消す必要もなく、リンクの間隔が空きます。

もう 1 つの日常的なパターンがメディアの行です。固定サイズのアイコンと、残りの幅を使って自分の列の中で折り返す文章です。

flex: none がそれを保証します。flex アイテムは初期状態で縮むので、円から flex: none を消し、文章からも flex: 1 を消すと、段落が円を幅約 23px まで押しつぶし、楕円になります。1 つのものをボックスの中央に置くなら、flexbox では 2 行です (justify-content: center; align-items: center)。ほかの方法との比較は div の中央寄せのページ にあります。

order とアクセシビリティ

order プロパティと -reverse の方向は、アイテムが 表示される 位置を変えるだけで、HTML の中の位置は変えません。スクリーンリーダーと Tab キーは HTML の順番に従うので、キーボードで操作する人は、画面の最初のリンクから最後のリンクに飛ぶことがあります。これらは見た目のためだけに使い、順番に意味があるときは HTML を変えましょう。

flexbox か grid か

flexbox は一度に 1 方向で動きます。行の中のアイテムは内容に合わせてサイズが決まり、(折り返しで) 2 行目ができても 1 行目とそろいません。grid は 2 方向で動きます。列と行を定義すると、アイテムがそこにはまります。ナビゲーションバー、ツールバー、フォームの行は flexbox、ギャラリーやサイドバー付きのページは grid です。

よくある間違い

  • 親ではなくアイテムに display: flex を付ける。 display: flex はコンテナに付け、その子要素がアイテムになります。
  • 高さがないのに align-items でアイテムが縦に動くと思う。 コンテナの高さが一番高いアイテムと同じなら、動く余地がありません。コンテナに高さを与えましょう。そうでなければ、正しく動いていてもすることがないだけです。
  • 文字が縮まずにはみ出す。 flex アイテムは min-width: auto です。縮ませたいアイテムに min-width: 0 を追加しましょう。
  • flex: 1 なのに幅が違うのはなぜ? flex: 1 のアイテムはスペースを均等に分けますが、内容が収まらないアイテム (長い URL、画像) はそれより小さくは縮みません。これも min-width: 0 で直ります。
  • アイテムの間に margin を付ける。 コンテナに gap を使いましょう。gap はアイテムの間にだけ入ります。
  • 不要に flex を入れ子にする。 flex アイテムになるのは直接の子要素だけです。孫要素は、その親も display: flex でない限り、通常のレイアウトに従います。

よくある質問

display: flex は何をしますか?

要素を flex コンテナにします。直接の子要素は flex アイテムになり、初期状態では横に並んで同じ高さに引き伸ばされます。justify-content、align-items、gap などのプロパティで、スペースの分け方を制御します。

flex: 1 はどういう意味ですか?

flex: 1 は flex: 1 1 0% の省略形です。アイテムは伸びることができ (flex-grow: 1)、縮むことができ (flex-shrink: 1)、サイズ 0 から始まります (flex-basis: 0%)。すべて flex: 1 のアイテムは空きスペースを均等に分けるので、内容が収まらない場合を除いて同じ幅になります。

justify-content と align-items の違いは何ですか?

justify-content は主軸 (横並びなら横方向) に沿ってアイテムを配置し、align-items は交差軸 (横並びなら縦方向) に沿って配置します。flex-direction: column では 2 つの軸が入れ替わり、justify-content が縦方向になります。

flexbox と grid のどちらを使うべきですか?

アイテムが内容に合わせてサイズが決まる 1 行か 1 列には flexbox を使います。ナビゲーションバー、ボタンのグループ、入力欄の横のラベルなどです。カードのグリッドやページのレイアウトのように、行と列をそろえたいときは grid を使います。

flex アイテムがコンテナからはみ出すのはなぜですか?

flex アイテムは初期状態で min-width: auto なので、一番長い単語や一番幅の広い子要素より小さくは縮みません。アイテムに min-width: 0 (または overflow: hidden) を指定すると縮めるようになり、たとえば text-overflow: ellipsis が効くようになります。

flexbox は span のようなインライン要素にも使えますか?

使えます。display: flex の要素はどれでも flex コンテナになり、その子要素は自分の display の値に関係なく flex アイテムになります。そのため <span> の子要素もインラインではなくなり、block のように幅、高さ、margin が効きます。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める