1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【CSS】フレックスボックスレイアウトの私的解釈

Last updated at Posted at 2025-02-24

個人的にいつもフレックスコンテナの justify-contentalign-itemsalign-content を試行錯誤的に記述してしまっていて、ほしい見た目にストレートフォワードに記述することができていなかったので、これらのプロパティを学んで自分なりに解釈しました。
私のようにフレックスボックスを何となく使っている人に参考になればという記事です。

この記事は、こう解釈すると CSS が書きやすいのではという記事であり、実際の描画処理の解説記事ではないです。解釈としても不正確な記述もあるかもしれません。取り上げているフレックスボックスのプロパティや値も網羅的ではありません。
[2025/02/25] 一部不正確な記述がありました ( 交差軸方向に余白がない状態だと align-content で交差軸方向に重力をかけてもアイテムは動けないと書いていますが、アイテムにちぢむ余地があれば重力をかけるとちぢみます)。後で修正します。

[2025/02/25] どのプロパティをどうするとどうなるかのツールを作成しました。
https://cookiebox26.github.io/games/misc/sample-flex-interactive.html

具体例に沿った説明

フレックスボックスは下図の 6 ステップの処理をしていると解釈できると思います。

image.png

上図の説明

  • 主軸方向が 4 パターンあるので 4 列描いています。主軸方向を「水色→ピンク色」、折り返して改行する方向を「明→暗」で表現しています (折り返しが逆の wrap-reverse は略)。
  • 上図で、アイテム 006 だけはサイズを指定していて (height: 30px; width: 30px;)、アイテム 012 だけは主軸方向へ可能な限りふくらむよう指定しています (flex: auto;)。
  • このとき、フレックスボックスは基本的には以下の処理をします (するようにみえます)。
    • STEP1. で、とりあえずアイテムを主軸方向 & 折り返し方向に自然に並べます
    • STEP2. で、各アイテムの主軸方向へのふくらませを行います (ただし、実際にふくらむのは、ふくらむよう指定されているアイテム 012 のみです)。
    • STEP3. で、各アイテムの交差軸方向へのふくらませを行います (ただ、サイズ指定がある アイテム 006 はふくらませた後にやっぱり元に戻します)。
  • さらに、フレックスコンテナに justify-contentalign-itemsalign-content プロパティが指定されているときは、以下の処理をします (するようにみえます)。
    • STEP4. で、justify-content の値にしたがって、主軸方向に重力を発生させます (ただ上図では値が space-between なので、重力というよりアイテム間斥力を発生させています)。なお、もしすべての行 (列) で主軸方向に余白がなかったら、この重力を発生させても意味がありません。
    • STEP5. で、align-items の値にしたがって、STEP3. での交差軸方向へのふくらませを解除し1、行 (列) 内に交差軸方向の重力を発生させます 2 (上図では値が center なのでアイテムが行 (列) の中央のラインに寄っています)。なお、もしすべてのアイテムがふくらませを解除しても行 (列) 内で交差軸方向に余白ができなかったら、この重力を発生させても意味がありません。
    • STEP6. で、align-content の値にしたがって、交差軸方向の重力を発生させます (上図では値が end なのでアイテムが暗い方に寄っています)。なお、もし交差軸方向に余白がなかったら、この重力を発生させても意味がありません。
      • したがって、アイテムに交差軸方向のサイズを指定して STEP3. のふくらませを解除するか、コンテナに align-items を指定して STEP3. のふくらませを解除する必要があります (はず)。

なお、上図の HTML ファイルは以下です (解釈を説明するため恣意的に記述しています)。
https://cookiebox26.github.io/games/misc/sample-flex.html

一般的 (?) な説明

これ以降の文章による説明では、一般的といってもコンテナの主軸方向 flex-direction がデフォルト値 row であるものとしますrow-reverse, column, column-reverse にあてはめる場合は、ところどころ読み替える必要があります。

フレックスボックスは以下の 6 ステップの処理をしていると解釈できると思います。

  • STEP1. コンテナにアイテムたちを自然に並べる
  • STEP2. アイテムたちの幅をふくらませる
  • STEP3. アイテムたちの高さをふくらませる
  • STEP4. コンテナ内に横方向の重力を発生させる (justify-content)
  • STEP5. アイテムを自然な高さに戻し行内で縦方向の重力を発生させる (align-items)
  • STEP6. コンテナ内に縦方向の重力を発生させる (align-content)

STEP1. コンテナにアイテムたちを自然に並べる

まずはコンテナの右上端から右に自然に (サイズを伸縮させずに) アイテムたちを並べます。
アイテムがはみ出たときは、コンテナに flex-wrap: wrap(-reverse); が指定されていれば折り返します。指定されていなければはみ出します。

STEP2. アイテムたちの幅をふくらませる

個々のアイテムの中に flex, flex-grow, flex-shrink, flex-basis が指定されているものがあるときは、それにしたがってそのアイテムの横幅をふくらませ (ちぢませ) ます。

STEP3. アイテムたちの高さをふくらませる

次に、アイテムたちの高さを同じ行内で一番高いアイテムと同じ高さまでふくらませ、それでもまだコンテナの高さに余白があれば、すべての行がその余白を平等に分け合うようにさらにアイテムたちの高さをふくらませます。
ただし、高さが明示的に指定されたアイテムについては、いったん高さをふくらませた場合の配置にした後で、指定された高さにちぢめます

STEP4. コンテナ内に横方向の重力を発生させる (justify-content)

もしコンテナに justify-content が指定されていたら、コンテナ内に横方向の重力を発生させてアイテムたちを移動します。start ならコンテナ左端への重力 3end ならコンテナ右端への重力、center ならコンテナ中央への重力、space-between ならアイテム間に斥力を発生させます。
※ すでにどの行もコンテナの幅に余白がないようなときは何も起きません。

STEP5. アイテムを自然な高さに戻し行内で縦方向の重力を発生させる (align-items)

もしコンテナに align-items が指定されていたら、高さをふくらませていたアイテムたちを行内で元の高さにちぢめると共に、start なら行の上端に向かって、end なら行の下端に向かって、center なら行の中央に向かって重力を発生させアイテムたちを移動します。ただし、個々のアイテムに align-self が指定されたものがあるときは、そのアイテムにだけはその値にしたがった重力を作用させます。
※ アイテムを自然な高さに戻しても行の高さに余白ができないときは何も起きません。

STEP6. コンテナ内に縦方向の重力を発生させる (align-content)

さらにコンテナに align-content が指定されていたら、コンテナ内に縦方向の重力を作用させてアイテムたちを行単位で移動します。start ならコンテナ上端への重力、end ならコンテナ下端への重力、center ならコンテナ中央への重力、space-between なら行間に斥力を発生させます。
※ すでにコンテナの高さに余白がないようなときは何も起きません。

まとめ

フレックスボックスは 6 ステップの処理をしていると解釈すると、意味がないプロパティの指定を回避し (Ex. 余白がない方向に重力を発生させても移動できないので意味がない)、ほしい見た目に必要十分な CSS の記述をできる気がします。

というか本来は、STEP3. まででアイテムを自動的にふくらませきってもらって、人間は配置について何も考えなくてよいというのがフレックスボックスレイアウトの真価だと思うので (?)、「アイテムをふくらませずにこのサイズにしなきゃやーやーなの」とする時点でそれが台無し (?) だと思いますが、そうしてできた余白をどの方向に詰めたいのかに基づいて重力を発生させようと考えるとストレートフォワードに CSS を書ける気がします。

参考文献

下記のページ及びリンク先の各プロパティのページを参考にしています。

  1. ただし、値を align-items: stretch; に指定した場合はふくらませは解除されず、重力も発生しません (交差軸方向にふくらみきっているのでどのみち動けない)。もっとも、この値はフレックスコンテナの初期値なので、明示的に指定する必要はありません。

  2. アイテムに align-self プロパティを設定することでアイテムごとに重力の方向を変えることもできます (後述)。

  3. start でも flex-start でもコンテナ左端への重力になります。flex-directionrow-reverse のときは後者 flex-start はコンテナ右端への重力になります。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?