フローレイアウトの実装方法

·
Cover for フローレイアウトの実装方法

フローレイアウト(Flow layout)は、Normal Flowとも呼ばれ、Webにおける各ボックスのデフォルトのレイアウト方式です。

多くのiOS開発者が、フロントエンド開発に初めて触れる際に、どこにでも出てくるものの、明確に説明することが難しいこの概念に戸惑います。直感的に理解しにくいのです。

ここでの重要なポイントは、Webレイアウトが元々テキストの組版のために設計されたため、後から導入されたFlexとは異なり、フローレイアウトの「原子的なレイアウト単位」は各要素に対応するボックスだけでなく、ボックス(ブロックボックス用)とテキスト(インラインボックス用)の両方を含むということです。

フローレイアウトには、インライン方向(inline direction)とブロック方向(block direction)の2つのレイアウト方向があります。

フローレイアウトの2つの方向

要素のdisplayがblock/inline-blockの場合、対応するRenderObjectはボックス(四角形で、折りたたまれない)として振る舞い、内部的にはwriting-modeに基づいて、インライン方向とブロック方向に分けることができます:

このようなボックスをブロックコンテナと呼び、このブロックコンテナ内の子要素は以下の2つの方法でのみ配置されます:

  • すべての子要素がインラインレベル(inlineまたはinline-block)の場合、インライン方向に配置される
  • それ以外(つまり、子要素にblockが含まれる場合)、ブロック方向に配置される

これら2つのルールをフローレイアウトの「公理」と考えることができます。実際の状況でこれらのケースに合わない場合、「匿名ブロック」を使用して実際の状況をこれら2つの公理に適合させます。

匿名ボックスの生成ルール

実際のDOM構造では、インラインとブロックの要素が共存する場合があります。このような場合、現在のコンテナはそれらのインライン子要素を匿名のブロックボックスでラップし、その後、ブロックレイアウトに従って子要素を配置する必要があります。

例えば:

匿名ボックスのラッピングに関する詳細なロジックは、別の記事「ブラウザはどのようにRenderObjectを生成するのか」で詳しく説明されているため、ここでは繰り返しません。

フローレイアウトの責務

  • フロー内のボックスのボックスモデルプロパティの計算を確実に行う
  • フロー内のインラインレベルボックスとテキストを混合して配置する
  • フロー内のブロックレベルボックスを垂直方向に配置する

ブラウザはフローレイアウトをどのように実装しているのか?

ブロック方向(すべての子要素がブロックの場合)

  1. まず、現在のボックスのコンテンツボックスの幅を計算する
  2. 現在のボックスのパディングとボーダーを計算し、パディングトップとボーダートップを現在のボックスの高さに追加する
  3. 子要素のレイアウトを呼び出し、幅、高さ、マージンなどを決定する
  4. 子要素のマージントップに基づいて要素のy座標を、マージンレフトに基づいてx座標を決定する
    1. 最初の要素の場合、親ボックスのマージントップとのマージン相殺を考慮する
    2. それ以外の場合、前のボックスとのマージン相殺を考慮する
  5. 子要素の高さを現在のボックスの総高さに追加する
  6. 次の要素に対してステップ2-4を繰り返す
  7. 最後の要素に対して、現在のボックスのマージンボトムとのマージン相殺戦略を計算し、パディングボトム、ボーダーボトムを追加する
  8. 現在のボックスにマウントされた配置済みボックスをレイアウトする
  9. 子要素にオーバーフロー動作があるかどうかを確認し、結果に基づいてスクロールバーを表示するかどうかを決定する

インライン方向(すべての子要素がインラインの場合)

  1. インラインウォーカーがすべてのインラインレベルボックス、フローティングボックス、改行ボックス、テキストを走査し、ラインボックスツリーを構築し、ボックスにレイアウトを実行する
  2. テキストレイアウトルールに従って、文字またはボックスを単位として配置する

付録

フローレイアウト実装時に考慮すべきその他のプロパティ

  • 配置モード(position):
    • 相対配置(relative):子要素の変位に影響
    • 絶対配置(absolute)、固定配置(sticky):要素の最終的な幅/高さの計算に影響
  • ボックスモデル:
    • ボックス境界(box-sizing):要素の最終的な幅/高さの計算に影響
    • 固有の寸法(img/videoのwidth/height属性):要素の最終的な幅/高さの計算に影響
    • 負のマージン:子要素の変位に影響
    • マージン相殺:ブロックとインラインの高さ計算に影響
    • 最大/最小幅/高さ(min/max-width/height):幅/高さの計算に影響
    • 方向/書き込みモード(direction/writing-mode):幅/高さの計算プロセスに影響
    • アスペクト比:要素の最終的な幅/高さの計算に影響
    • 垂直配置(vertical-align):インラインフォーマッティングコンテキスト内の要素の変位に影響
  • テキスト:
    • 文字のオーバーフロー(overflow-wrap/hyphens/text-overflow/white-space):テキストを含む要素の最終的な幅/高さの計算に影響
    • 文字組版
      • vertical-align:個々のインライン要素の変位に影響
      • text-align:ブロック内のテキストの左右の端に影響
  • レイヤー関係(z-index):レイアウト計算オブジェクトに影響(z-indexが異なる要素は別々にレイアウトする必要がある)
  • フロート:ブロックコンテナの高さに影響、インラインコンテナの幅に影響