Video summary
How Clay's UI Layout Algorithm Works
Main summary
Key takeaways
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:
- Position is relative to the container
- Element coordinates are defined relative to their parent.
- 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:
- Compute sizes by traversing the tree bottom-up (described via how “open/close” scopes execute).
- 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)
- per-axis alignment:
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.
Translate summary in another language
Ask questions to this video
Chat for follow-up questions, clarifications, and source-backed answers.