Video summary

How Clay's UI Layout Algorithm Works

Main summary

Key takeaways

Technology

Clay: how its UI layout algorithm works

Overview of Clay

  • Clay is an open-source UI layout library for building interfaces that adapt to screen size and changing content.
  • Its layout computation is described as surprisingly compact: three core functions totaling about ~800 lines of code—notably “easier than people expect,” despite intimidation around UI layout “edge cases.”

Core problem and design insights

Naive UI layout approaches tend to cause either:

  • Unfixable edge cases, or
  • Redundant work.

Clay’s design is guided by two key conceptual insights:

  1. Position is relative to the container
    • Element coordinates are defined relative to their parent.
  2. Size depends on contents
    • Computing size often requires sizes of nested children, creating a recursive dependency.

UI hierarchy as a tree

Clay represents UI as a tree (UI hierarchy):

  • Root: outer container (e.g., dropdown background)
  • Children: menu items
  • Grandchildren: text labels and icons

It provides a macro-based API (described as clay) that builds these nested structures.

Basic layout model and auto-layout directions

Each layout element stores:

  • position
  • size
  • children
  • visual properties (e.g., background color)

Clay supports directional layout:

  • Default: children laid out left-to-right
  • Alternative: top-to-bottom

Relevant layout features mentioned:

  • padding: offsets children within a parent
  • childGap: adds space between sibling children along the layout direction
    • implemented using the “fence post” gap concept

Fit sizing (tight-to-content) requires multiple passes

In fit mode, the container’s size is computed based on its children.

A key realization:

  • Layout can’t always be computed in one pass, because parent sizes depend on child sizes.

Clay uses two-pass processing:

  1. Compute sizes by traversing the tree bottom-up (described via how “open/close” scopes execute).
  2. Compute positions afterward—after final sizes are known.

How fit mode computes parent size

Parent sizing depends on axis:

  • Along the layout axis: use the sum of children sizes
  • Across the layout axis: use the max of children sizes

The close/size calculations explicitly account for:

  • padding
  • childGap

This is what allows “fit” containers to wrap their contents correctly.

Separating sizing from positioning (robustness gain)

With flexible layouts, final positions can’t be known until all child sizes are resolved.

Clay improves robustness by splitting the process into:

  • size calculation first
  • position calculation later

It also treats X/Y as the same concept by framing everything around the layout direction, so width/height logic can share the same underlying function.

Grow sizing (expand to available space)

In grow mode, containers expand beyond “fit” by filling extra space in the parent.

Clay uses an additional multi-pass step:

  • Grow cannot be handled correctly in the same pass as fit, because it requires knowledge of the overall available space.
  • Therefore, Clay adds a separate pass for grow expansion.

Remaining space calculations use:

  • parent fixed dimensions
  • padding
  • fit-like child sizing rules (sum/max)
  • childGap (“fence post” logic)

When multiple children are growable:

  • Clay tries to make growable siblings end up the same size
  • It repeatedly expands the currently smallest growable elements until they match, then expands all together
  • Limitation noted: if one element is already larger than available space, exact equality may be impossible.

Text layout handling (preferred/minimum widths, wrapping)

Text elements have intrinsic dimensions because Clay measures rendered text (unlike rectangles, which have no intrinsic size).

Problems addressed:

  • Very long text without explicit newlines can produce extremely large widths, breaking horizontal layouts.

Clay introduces:

  • Preferred width: how much space text wants (e.g., largest word size)
  • Minimum width: the smallest width it can shrink to (so text doesn’t collapse too far)

Shrink behavior (reverse grow-like strategy)

When content exceeds the container, Clay shrinks widths in a “grow-like” reverse process:

  • shrink the largest preferred items downward toward smaller ones
  • if an element hits its minimum width, it is removed from further shrinking distribution

Wrapping and height propagation

After determining widths:

  • Clay performs text wrapping
    • finds wrap points (example: wrap at spaces in English)
  • It increases text element height line-by-line until the full content fits

Because wrapping changes height, Clay refines sizing by:

  • splitting width/height into separate phases
  • deferring height fitting until after wrapping
  • then running height fit/grow passes so heights propagate correctly through the tree

Additional layout features added later

  • Minimum and maximum sizing
    • Minimum width prevents overly skinny UI
    • Maximum width triggers wrapping earlier
    • implemented in fit and grow passes by:
      • clamping sizes
      • removing elements that hit min/max during distribution
  • Alignment (a final positioning step; position-only, not size)
    • per-axis alignment:
      • X: left / center / right
      • Y: top / center / bottom
    • center alignment distributes remaining space (divide by 2 along the axis)

Tutorial/demo: building a flexible context menu

The video ends by building a context menu using Clay features:

  • Root container
    • purple
    • fit to contents
    • then constrained with min/max width to trigger wrapping
  • Menu items
    • laid out vertically (switches from left-to-right to top-to-bottom)
  • Menu item sizing
    • menu items set to grow so they share consistent width
    • icon positioned via an internal layout trick:
      • label container with width grow pushes the icon to the right
  • Visual tweaks
    • padding and childGap
    • minimum height (e.g., 80) for consistent row height
    • Y alignment = center inside menu items
    • long labels wrap gracefully via max width

Main speakers / sources

  • Speaker: the video author/primary presenter (not named in the provided subtitles).
  • Source references mentioned:
    • “constraint solver” papers
    • source code of other UI layout libraries (referenced conceptually rather than via specific named authors in the subtitles).

Rate this summary

Your feedback will help improve summaries.

Improve this summary

Reprocess with a stronger model when the summary feels incomplete or inaccurate.

Pro

Translate summary in another language

Pro

Ask questions to this video

Chat for follow-up questions, clarifications, and source-backed answers.

Coming soon

Share this summary

Original video