How to Implement Flow Layout?

·
Cover for How to Implement Flow Layout?

Flow layout, also known as Normal Flow, is the default layout method for every Box in the Web.

Many iOS developers, when first encountering frontend development, are often confused by this concept that appears everywhere but is difficult to explain clearly. It just doesn’t seem intuitive.

The key point here is that, since Web layout was originally designed for text typesetting, unlike Flex which was introduced later, the “atomic layout unit” in Flow layout isn’t just the Box corresponding to each element, but includes both Boxes (for Block Boxes) and text (for Inline Boxes).

In Flow layout, there are two layout directions: inline direction and block direction.

Two Directions in Flow Layout

When an element’s display is block/inline-block, its corresponding RenderObject behaves as a box (square-shaped, won’t collapse), and internally, based on writing-mode, it can be divided into inline direction and block direction:

We can call such a box a block container, and within this block container, child elements are arranged in only two ways:

  • When all child elements are inline-level (inline or inline-block), they are arranged in the inline direction
  • Otherwise (i.e., when child elements include block), they are arranged in the block direction

We can consider these two rules as the “axioms” of flow layout. In real situations where things don’t match these cases, “anonymous blocks” are used to make the actual situation conform to these two axioms.

Anonymous Box Generation Rules

In actual DOM structures, there might be cases where both inline and block elements exist. In such cases, the current container needs to wrap those inline child elements in an anonymous Block Box, and then arrange child elements according to block layout.

For example:

The detailed logic for wrapping anonymous Boxes has been thoroughly explained in another article “How Browser Generates RenderObject”, so we won’t repeat it here.

Flow Layout Responsibilities

  • Ensure box model properties are calculated for Boxes in Flow
  • Mix and arrange inline-level boxes with text in Flow
  • Arrange block-level boxes vertically in Flow

How Do Browsers Implement Flow Layout?

Block Direction (When All Children Are Block)

  1. First, calculate the content box width of the current box
  2. Calculate the current box’s padding and border, add padding top and border top to the current box’s height
  3. Call children’s layout to determine their width, height, margin, etc.
  4. Determine element’s y coordinate based on child element’s margin top, and x coordinate based on margin left
    1. For the first element, consider margin collapse with parent box’s margin top
    2. Otherwise, consider margin collapse with previous box
  5. Add child element’s height to current box’s total height
  6. Repeat steps 2-4 for next element
  7. For the last element, calculate margin bottom collapse strategy with current box’s margin bottom, and add padding bottom, border bottom
  8. Layout positioned boxes mounted in current box
  9. Check if children have overflow behavior and decide whether to show scroll bar based on results

Inline Direction (When All Children Are Inline)

  1. Inline walker traverses all inline-level boxes, floating boxes, line break boxes, and text, builds line box tree, and performs layout on boxes
  2. Arrange according to text layout rules, using character or box as unit

Appendix

Other Properties to Consider During Flow Layout Implementation

  • Positioning mode (position):
    • Relative positioning (relative): Affects child element displacement
    • Absolute positioning (absolute), sticky positioning (sticky): Affects element’s final width/height calculation
  • Box model:
    • Box boundary (box-sizing): Affects element’s final width/height calculation
    • Intrinsic dimensions (width/height attributes of img/video): Affects element’s final width/height calculation
    • Negative margin: Affects child element displacement
    • Margin collapse: Affects block and inline height calculation
    • Maximum/minimum width/height (min/max-width/height): Affects width/height calculation
    • Direction/writing-mode: Affects width/height calculation process
    • Aspect ratio: Affects element’s final width/height calculation
    • Vertical alignment (vertical-align): Affects displacement of elements in inline formatting context
  • Text:
    • Character overflow (overflow-wrap/hyphens/text-overflow/white-space): Affects final width/height calculation of elements with text
    • Character typography
      • vertical-align: Affects individual inline element displacement
      • text-align: Affects left/right edges of text in block
  • Layer relationship (z-index): Affects layout calculation objects (elements with different z-index should be laid out separately)
  • Float: Affects block container height, affects inline container width