Menu

CSS flex-wrap と flex-direction: 折り返しと縦並び

flex-wrap は flex アイテムを 1 行に詰めるか次の行に折り返すかを決め、flex-direction は横に並べるか縦に並べるかを決めます。どちらもライブ例で解説し、flex-flow のショートハンド、align-content、メディアクエリなしのレスポンシブなカードの並びも紹介します。

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

flex-wrap: 1 行か、必要なだけの行か

初期状態の flex コンテナは、すべてのアイテムを 1 行に置き (flex-wrap: nowrap)、収まるように縮めます。flex-wrap: wrap にすると、アイテムはサイズを保ったまま次の行に移ります:

各アイテムは 100px を求め、それが 340px のボックスに 5 つあります。5 つのアイテムと 8px のすき間 4 つで 532px 必要なので、折り返しがないと、flex アイテムは初期状態で縮むため、それぞれ約 62px に押しつぶされます。wrap なら 100px のままで、1 行目に 3 つが収まり、残りの 2 つは 2 行目に移ります。

flex-wrap の値

値動き
nowrap (初期値)1 行。アイテムは縮み、それ以上縮めなくなるとコンテナからはみ出す
wrap収まらないアイテムは下に新しい行を作る
wrap-reverse同じだが、新しい行は上に積まれる。1 行目が一番下になる

アイテムの折り返しを見る

スライダーをドラッグして、コンテナの幅を変えてください。表示欄が行の数と、各行のアイテムの数を示します:

400px では、90px のアイテム 4 つと 8px のすき間 3 つ (384px) が 1 行に収まるので、4 + 2 になります。620px の方へドラッグすると 6 つすべてが 1 行に収まり、120px の方へドラッグすると各アイテムが 1 行ずつになります。

flex-direction: 横並びか縦並びか

flex-direction はアイテムが並ぶ方向、つまり 主軸 を決めます:

値アイテムの並び最初のアイテム
row (初期値)横に、書字方向に行の始まり
row-reverse横に、逆順に行の終わり
column縦に、上から下へ一番上
column-reverse縦に、下から上へ一番下

2 つの row のボックスでは、align-items: stretch が行と直角の方向に働くので、アイテムはボックスの高さいっぱいに伸びます。column のボックスでは、同じ理由で 幅 いっぱいに伸びます。軸が回転し、配置のプロパティもすべて一緒に回転したのです (justify-content のページ で詳しく見られます)。

flex-flow: 2 つを 1 行で

flex-flow は、flex-direction、flex-wrap の順に書くショートハンドです:

.cards { flex-flow: row wrap; }      /* flex-direction: row; flex-wrap: wrap; */
.stack { flex-flow: column nowrap; } /* flex-direction: column; flex-wrap: nowrap; */

メディアクエリなしで wrap を使うレスポンシブなカード

各アイテムに flex: 1 1 180px で出発点のサイズを与え、行を折り返させます。各アイテムは行を埋めるように伸び、行にもう 1 つ 180px のアイテムが入らなくなると、次のアイテムが折り返します:

幅約 800px のプレビューでは、1 行目に 3 枚のカード (それぞれ約 253px) が収まり、残りの 2 枚が 2 行目を分け合って、それぞれ約 386px まで伸びます。これが flexbox の動き方です。各行が自分のスペースを分けるので、短い最後の行のカードは上の行より広くなります。最後のカードもほかと同じ幅にしたいなら、代わりに grid と repeat(auto-fill, minmax(180px, 1fr)) を使います (grid のページ を参照)。

align-content: 行と行の間隔

コンテナが折り返していて、行の合計より高いとき、行をどこに置くかを決めるのが align-content です。justify-content と同じ値に加えて stretch を使えます:

1 つ目のボックスでは、2 つの行がどちらも上にあります。2 つ目では 1 行目が上、2 行目が下にあり、余った高さはすべてその間に入ります。

逆順とアクセシビリティ

row-reverse、column-reverse、wrap-reverse は、アイテムが描かれる位置を変えるだけです。スクリーンリーダーと Tab キーは HTML の順番に従うので、キーボードで操作する人は、見た目と逆の方向にアイテムを移動します。逆順は見た目の効果のためだけに使い、順番に意味があるときは HTML で変えましょう。

よくある間違い

  • アイテムが折り返さずに縮む。 flex: 1 のアイテムは flex-basis 0 から始まり、1 行に押し込まれます。flex: 1 1 200px のように本当の basis を与えましょう。
  • flex-wrap をアイテムに書く。 flex コンテナに書きます。
  • 折り返した行の間隔を align-items で調整しようとする。 それは各行の中でアイテムを揃えるものです。行そのものは align-content で動きます。
  • 最後に 1 つだけ残ったアイテムが行全体に引き伸ばされる。 アイテムが 1 つの行での flex-grow の結果です。すべてのカードを同じ幅にしたいなら grid を使いましょう。
  • flex-direction: column が高さを埋めると思う。 縦並びのコンテナは、height を与えない限り内容と同じ高さしかないので、justify-content が働く余地がありません。

よくある質問

flex-wrap: wrap は何をしますか?

flex アイテムが 1 行に収まらないとき、新しい行に移れるようにします。初期値の nowrap では、アイテムは 1 行にとどまって縮み、それ以上縮めなければコンテナからはみ出します。

flex-wrap が効かないのはなぜですか?

折り返しが起きるのは、アイテムの出発点のサイズの合計がコンテナより大きいときだけです。flex: 1 のアイテムは flex-basis 0 から始まるので、折り返しません。本当の出発点のサイズ (flex: 1 1 200px や width: 200px) を与えましょう。flex-wrap がアイテムではなく flex コンテナに付いているかも確認します。

flex-direction の row と column の違いは何ですか?

row (初期値) はアイテムを書字方向に横に並べ、column は上から下に縦に積みます。主軸も一緒に回転するので、縦並びでは justify-content が縦方向、align-items が横方向に働きます。

flex-flow とは何ですか?

flex-direction と flex-wrap を 1 つの宣言で書くショートハンドです。flex-flow: row wrap; は flex-direction: row; flex-wrap: wrap; と同じです。

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

align-items はアイテムをその行の中で配置します。align-content は行そのものをコンテナの中で配置するので、コンテナが flex-wrap: wrap で、行の合計より高いときにだけ意味があります。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める