【CSS】 flexboxを使って柔軟に要素を並べる

flexboxは、要素の並び方や大きさ、位置揃えなどを柔軟に制御できる画期的な機能です。

レスポンシブデザインにはもはや欠かせない要素となっています。

まずはflexboxを利用した例を見てみましょう。

See the Pen css flex1 by Totori (@souki202) on CodePen.

単に横に並んでいるだけのように見えますが、親要素に対して

  • 内側の各コンテンツの表示領域はそのままに
  • 親の幅全体を利用し
  • 均等な間隔で
  • 上下中央揃えで

表示するという、flexが無い時代では非常に難しかったことをしています。ここから、各プロパティを見ていきましょう。

flexの設定

display

displayは、noneにして非表示にしたり、inline-blockにしてinlineながらにblockとしても振る舞えるようにしたりなどに利用します。

今回は、ここにflexを指定します。flexは、その要素自体はblockと同じような挙動ですが、子要素に対する扱いがblockとは異なります。

div {
    display: flex;
}

See the Pen css display flex by Totori (@souki202) on CodePen.

しかし、このままでは普通に横に並ぶだけです。そのうえ、横方向にはみ出します。

折り返し設定 (flex-wrap)

flex-wrapプロパティを用いることで、要素の並びを折り返すことができます。デフォルトでは折り返さない(nowrap)ですが、普通は折り返すのでflex-wrap: wrap;を指定しておくのが確実です。

See the Pen css flex-wrap by Totori (@souki202) on CodePen.

並びの向き (flex-direction)

flex-directionプロパティを用いることで、横方向に並べるか、縦方向に並べるかを選択できます。例えば、@media (max-width: 480px){...}等と合わせて、PC表示なら横方向にメニューを並べ、モバイル表示なら縦に並べる、といった切り替えも楽にできます。

縦方向にする場合、デフォルトでは左右いっぱいに要素が広がります。

See the Pen css flex-direction by Totori (@souki202) on CodePen.

縦方向に並べる場合、heightautoであれば折り返しません。これは普通の要素の挙動ですね。heightを指定し、かつwrapを指定している場合、折り返し時に横方向に親要素の範囲を超えて飛び出すかもしれないので注意が必要です。

row-reversecolumn-reverseもありますが、reverse系は使う機会はあまりありません。逆順で表示したいときに利用する可能性があるという程度です。

並ぶ位置設定 (justify-content)

justify-contentプロパティは、flex内の子要素が並ぶ間隔を指定します。

See the Pen css justify-content by Totori (@souki202) on CodePen.

  • start, end
    • それぞれ先頭に寄せる、末尾に寄せる
  • left, right
    • それぞれ左端、右端に寄せる
  • flex-start, flex-end
    • それぞれフレックスコンテナ内の先頭、末尾に寄せる
    • flex-startがデフォルト
  • center
    • 中央寄せで並ぶ
  • space-between
    • 親要素の幅いっぱいを使うようにして、均等間隔で並ぶ
  • space-around
    • 各要素を均等に配置し、各要素の両側に半分の大きさの間隔を置く
  • space-evenly
    • 各要素を均等に配置し、各要素の周りに同じ大きさの間隔を置く
  • stretch
    • 各要素を均等に配置し、サイズがautoである要素は親要素に合わせて引き伸ばす
    • 親がautoの場合は親要素のサイズが定まらないため、機能しない

よく利用するのはspace-xx系とcenterです。flex-startはデフォルトなのでわざわざ指定する必要はあまりありません。

位置揃え (align-items)

align-itemsプロパティでは、各項目の位置揃えを指定します。

See the Pen css align-items by Totori (@souki202) on CodePen.

  • normal
    • 初期値
  • stretch
    • 要素を伸縮して揃える
  • center
    • 中央揃えで配置
  • start
    • 始点に揃える
    • 横方向の並べ方なら上寄せ, 縦方向なら左寄せが通常
  • end
    • 終点に揃える
  • flex-start
    • フレックスコンテナ内の始点に配置
  • flex-end
    • フレックスコンテナ内の終点に配置
  • baseline
    • ベースラインに揃える
    • ベースラインは, 英字の下に飛び出さない文字の下端部分の高さ
  • first baseline, end baseline
    • それぞれ, 最初のベースライン, 最後のベースラインに揃える

flex内の各要素の設定

位置揃え (align-self)

align-itemsでは全ての要素に対して適用しましたが、align-selfを利用すると要素ごとに指定できます。

See the Pen css align-self by Totori (@souki202) on CodePen.

flex-grow, flex-shrink

それぞれの要素で、スペースが余っていたり足りなかったりする場合に、どれを優先的に大きく、小さくするかを指定するものです。

See the Pen css flex-grow shrink by Totori (@souki202) on CodePen.

特にgrowの例を見ると、最も大きいものだけが広がるわけではなく、指定した値に応じて広がる度合いが変化することがわかります。0とすれば基本的に伸長されません。

デフォルトは0であるため、1つだけflex-grow: 1;、ほかを指定なしとすれば、flex-grow: 1;となっているものが親要素の残りのスペース全体を埋めます。

shrinkも同様で、値の大きさに応じて、スペースが足りない場合に縮まる量が決まります。0とすれば基本的に全く縮まらないため、親要素からはみ出す場合があります、

基本の大きさを設定 (flex-basis)

そのflexの項目で、初期の大きさを設定するものです。あくまで初期の大きさであり、他のプロパティによってはこれより大きくなったり、小さくなったりします。

See the Pen css flex-basis by Totori (@souki202) on CodePen.

この例を見ると、500pxを指定している例では、実際の結果が500pxではなくもっと小さい大きさになっていることがわかります。あくまで初期値であり、必ずそのサイズになるというわけではないことがわかります。

.f5の例では、flex-basis: 0;で初期値は0ですが、flex-grow: 1;により、親要素の隙間を埋めるように引き伸ばされています。

min-contentmax-contentはまだ対応ブラウザが少ないため、細かい説明は省略します。

max-widthmin-widthと組み合わせ、growする上限を付けたり、shrinkする下限を付ける、といったことも多いです。

flexプロパティ

これは、display: flex;flexではなく、flexというプロパティです。これは、flex-shrinkflex-growflex-basisの値を一括で設定するためのものです。

See the Pen css flex prop by Totori (@souki202) on CodePen.

p {
    flex: 1; /* 単位がない数値が1つなら, flex-grow */
    flex: 10px; /* 単位がある数値またはbasisのキーワードが1つなら, flex-basis */
    flex: min-content; /* 同上 */

    flex: 1 2; /* 数値が2つ, かつ2つ目に単位がなければ, flex-grow flex-shrink */
    flex: 1 20em; /* 数値が2つ, かつ2つ目に単位またはbasisのキーワードがあれば, flex-grow flex-basis */

    flex: 1 2 300pt; /* 数値が3つなら, flex-grow flex-shrink flex-basis */
}
  • 1つ目の例は、flex-growが1、2、3と指定されているのと同等の状態なため、flex-growに応じた幅になります
  • 2つ目の例は、flex-growが1、2、3、flex-shrinkがすべて1のため、幅が足りていないことからflex-growが小さいものがより縮まっています
  • 3つ目の例は、flex-basisがそれぞれ10px、100px、500pxですので、それに応じた幅になります。ここで、全体の幅が足りないため縮んでいます
  • 4つ目の例は、flex-basisが10px、50px、100pxですが、flex-growが3、2、1と並んでいるため、結果的にすべて似たような幅になっています
  • 5つ目の例は、極端に大きい幅を指定しているものにflex-shrink: 1;が、ほかがflex-shrink; 0のため基本的に縮まらない設定です。そのため、1個目を小さくした後、flex-shrink: 0;の要素がはみ出ます。

flex-growflex-shrinkflex-basisは、いずれか1つだけなら挙動がイメージしやすいですが、3つ組み合わせると複雑な動きになります。

とはいえ、普段はそこまで複雑な設定はしません。まずは全項目で同じ設定にしたときにどう動くかを様々な値で試してみましょう!

まとめ

flexboxの良いところは、項目の並び方や大きさ、並ぶ向きなどを柔軟に設定できることです。柔軟さを活かしたレスポンシブなサイトはしばしば見られます。

非常に重要なプロパティなので、まずは並べる方向や位置揃えなど、簡単なところから試してみましょう!

同じように要素の並べ方を指定するグリッドレイアウトに関しては下のページにあります。

flexbox thumb

役に立ったらシェアしよう!