3秒でわかる
Flexbox の子要素を 1 行に押し込むか、はみ出す分を次の行へ送るかを決める CSS プロパティ。画面幅で崩れないカード並びの要になります。
もう少し詳しく
どういうものか
display を flex にした親要素の中で、子要素が横幅に収まらなくなったときの振る舞いを決める CSS のプロパティです。値は 3 つあります。既定値の nowrap は折り返さず、幅が足りなければ子要素そのものを縮めて 1 行に押し込みます。wrap は入り切らない子要素を次の行へ送ります。wrap-reverse も折り返しますが、新しい行が上へ積まれる形になります。
つまり「はみ出したときに、要素をつぶすのか、行を増やすのか」という二択を宣言するプロパティだと考えると分かりやすくなります。
なぜ必要か
Flexbox は既定で折り返さない設計になっています。そのため、カードを 4 枚横に並べたレイアウトをスマートフォンで開くと、カードが折り返さずに 4 枚のまま細長くつぶれ、中の文字が縦一列になるという崩れ方をします。ここで折り返しを許可すれば、狭い画面では 2 枚ずつ、さらに狭ければ 1 枚ずつ、と自然に段が増えていきます。
メディアクエリで幅ごとに列数を書き分けなくても、要素の最小幅と折り返しの許可だけでレスポンシブになるのがこのプロパティの効きどころです。
具体例
カード一覧を、幅に応じて自動で段組みにする書き方です。
.card-list {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.card {
/* 伸びる・縮む・基準幅 の順に指定する */
flex: 1 1 240px;
min-width: 0;
}flex の第 3 引数 240px が「このくらいの幅を確保したい」という基準になり、確保できなくなった時点で次の行へ送られます。
つまずきやすいところ
折り返しを許可したのに 1 行のままになる場合、子要素が縮める設定のままになっていることを疑います。基準幅を 0% や auto にしていると、要素はいくらでも縮めるので折り返す理由が生まれません。
長い英単語や URL を含むカードが縮まないケースもよく起きます。子要素に min-width の初期値 auto が効いていて、中身の最小幅より小さくなれないためです。子要素側に min-width を 0 にする指定を足すと解決します。
折り返した行の間隔を margin で作ると、最後の行の下に余分な余白が残ります。gap を使えば行間と列間の両方をまとめて扱えて、端の余白も発生しません。
似た用語との違い
| プロパティ | 決めること |
|---|---|
| flex-wrap | 折り返すかどうか |
| flex-direction | 主軸を横にするか縦にするか |
| flex-flow | 上記 2 つをまとめて書く省略記法 |
| align-content | 折り返して複数行になったときの、行全体の寄せ方 |
align-items は 1 行の中での揃え方、align-content は行が 2 行以上あるときの揃え方で、折り返しを有効にして初めて align-content が意味を持ちます。
覚え方
wrap は「包む、巻く」。行の端まで来た文章が次の行へ回り込むのと同じ動きだと結び付けておくと、値の名前で迷わなくなります。
