FlexBox: The Algorithm (Part 1)

محمّدمحمّد
3 min read

Intro

Flexbox is a well-known layout algorithm, used by many web developers and frameworks such as Bulma. This document tries to demystify the algorithm behind it.

Goal

For part 2: A working implementation of FlexBox in Pure Go (and maybe in WGSL or HLSL).

The Web’s FlexBox

Definitions

  • Box: The area given to the flex-box

  • Direction: The axis it spans along

    • Row: X-axis

    • Column: Y-axis

  • Main Axis: The axis defined by Direction

  • Cross Axis: The other axis

  • Item: a renderable entity that has width and height

  • Gap: a predefined value that adds defined gaps between elements

    • Row Gap: functional in Direction: Column or with wrap between main axes in the other direction.

    • Col gap: functional in Direction: Row or with wrap between main axes in the other direction.

  • Wrap: allows elements to flow to the next {direction} when the current one is full based on combined basis.

    • In wrap mode, the cross-axis length is controlled by justify-items . align-items values act differently because they no more hold power over the whole cross-axis. They act within each cross-axis dedicated space iff there’s available space (only with justify-items: stretch
  • Align: The CSS version has 3 types of alignments

    • align-items: aligns items on the cross axis. refer to Wrap. possible values:

      • start: at the start of the cross axis

      • end: at the end of the cross axis

      • center: at the center of the cross axis

      • stretch: the items height will fill the span of the cross axis

      • baseline = default = start (in our case we won’t define it)

    • justify-content: aligns items on the main axis. Functional only when no grow or shrink operations happen.Possible values:

      • start: puts items at the start of the main axis

      • end: at the end of the main axis

      • center: at the center of the main axis

      • space-around: divides the excess space across all elements with each element having 50% of allocated space before and 50% after. That means we have 100% between each element and 50% on the outer edges.

      • space-between: the remaining space is divided and put between elements.

    • align-content: functional only with wrap. aligns the main-axes across the cross-axis. Possible values:

      • start

      • end

      • center

      • space-around

      • space-between

      • stretch: stretches each main axis to fill excess space.

Impression

The CSS implementation is clunky and confusing to say the least. The wrap’s special cases causing unexpected behavior, along with different naming of similar things, all are rather unfortunate. There’s no doubt that this layout system was designed by a smart people who don’t need my endorsement, but the context of the web is a rotten one that leads to such monstrosities.

Plan

Based on the impression, I plan to divide the work on the algorithm into 2 distinct types: Flex and WrapFlex. The alignment and justification of each will be defined separately. Based on my experience, Flex is the more common usecase. I’ll try to make a bridge to ease transition to WrapFlex when it’s needed.

0
Subscribe to my newsletter

Read articles from محمّد directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

محمّد
محمّد