If you’ve ever hand-coded a Figma design into HTML/CSS, you’ve spent significant time translating Auto Layout into Flexbox. The two concepts overlap heavily — but the edge cases are where automated tools either succeed or fall apart.
This guide maps Figma Auto Layout to CSS Flexbox in detail. We cover the straightforward translations first, then the cases where things get complicated: nested structures, sizing modes, child-level controls, and the patterns that consistently trip up conversion tools.
Why Figma Auto Layout Maps to Flexbox
Figma Auto Layout was introduced with CSS Flexbox in mind. The terminology and the underlying behavior are deliberately similar. Direction, alignment, spacing, padding — these concepts appear in both systems with nearly identical roles.
For most Auto Layout frames, the translation to Flexbox is mechanical:
layoutMode: HORIZONTALbecomesflex-direction: rowlayoutMode: VERTICALbecomesflex-direction: columnprimaryAxisAlignItemsbecomesjustify-contentcounterAxisAlignItemsbecomesalign-itemsitemSpacingbecomesgap- Padding values map directly
A Figma frame with horizontal Auto Layout, centered alignment, and 16px spacing becomes:
.container {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 16px;
padding: 16px 24px;
}
This is the easy case. Most professional implementers can write this CSS in their sleep. The real value of automation comes from handling the cases that aren’t easy.
Sizing Modes: Where It Gets Complicated
Figma Auto Layout frames have sizing modes on both axes:
- FIXED — set to a specific size
- HUG — fit to content
- FILL — fill the available space in the parent
Each of these maps to different CSS depending on whether it’s the primary or counter axis.
FIXED sizing
The straightforward case. Just set width or height explicitly:
.box {
width: 320px;
}
HUG sizing
HUG means the element fits its content. In CSS, this is fit-content or, in many cases, leaving the dimension unset (since Flex children default to content size in some contexts).
.box {
width: fit-content;
}
FILL sizing
FILL on the primary axis is flex-grow: 1. FILL on the counter axis is align-self: stretch (or the parent’s align-items: stretch).
.box {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0;
}
The Combinatorial Problem
Each axis can be independently FIXED, HUG, or FILL — giving nine possible combinations per element. A button might be HUG on the primary axis (content width) and FIXED on the counter axis (40px height). A card might be FILL on both. A modal might be FIXED on both.
Hand-writing CSS for each of these is tedious. Automating it correctly requires careful per-axis logic — and this is one of the main places where Figma-to-code tools differentiate themselves on output quality.
Child-Level Properties: layoutGrow and layoutAlign
So far we’ve covered the parent’s settings. But Figma also provides child-level controls:
- layoutGrow — whether the child fills available space along the primary axis
- layoutAlign — how the child aligns on the counter axis
layoutGrow
Maps directly to flex-grow:
.child {
flex-grow: 1; /* equivalent to layoutGrow: 1 */
}
layoutAlign
Maps to align-self with the following correspondence:
STRETCH→align-self: stretchMIN→align-self: flex-startCENTER→align-self: centerMAX→align-self: flex-endINHERIT→ inherits from parent (no explicit CSS needed)
These child-level overrides are what enable mixed layouts: a row of three items where the first and last hug content while the middle one fills the gap.
Nested Auto Layout: The Recursive Challenge
Real Figma files rarely have a single flat Auto Layout. They have layouts inside layouts. A header contains a logo, a nav, and a button — each with their own internal structure.
To translate this correctly, an automated tool needs to recursively process each nested frame, generating the appropriate Flexbox context at each level. The pseudocode looks like:
function processNode(node) {
if (node.layoutMode === 'HORIZONTAL') {
emit('display: flex; flex-direction: row;');
} else if (node.layoutMode === 'VERTICAL') {
emit('display: flex; flex-direction: column;');
}
// emit padding, gap, alignment...
for (const child of node.children) {
processNode(child); // recursive
}
}
Simple in concept. The complications come when:
- A frame in the middle of the tree has no Auto Layout (layoutMode: NONE) — children fall back to absolute positioning relative to that frame
- Sizing modes interact across levels (a HUG parent containing a FILL child creates a circular dependency)
- Constraints differ between Auto Layout and non-Auto-Layout frames in the same hierarchy
Edge Cases That Trip Up Conversion Tools
These are the patterns that consistently cause problems in automated Figma-to-Flexbox conversion. Knowing them helps you evaluate any tool you might be considering.
1. HUG parent with FILL child
A parent set to HUG (fit to content) containing a child set to FILL (fill the parent) creates a logical contradiction. The parent says “size me to fit my child,” and the child says “size me to fit my parent.”
Figma resolves this by treating the FILL as HUG when this combination occurs. CSS doesn’t have an automatic resolution — the conversion tool needs to detect this case and decide which axis takes precedence.
2. Mixed Auto Layout and non-Auto-Layout in the same hierarchy
If a parent uses Auto Layout but one of its children doesn’t, the non-Auto-Layout child’s children need absolute positioning relative to that child frame. The conversion has to switch from Flexbox mode to absolute positioning mid-hierarchy.
3. Complex constraints and sizing combinations
Figma supports constraints (Top, Left, Center, etc.) that apply when Auto Layout is not active. When constraints and Auto Layout interact in a hierarchy, the conversion logic needs to handle both systems coherently.
4. Padding asymmetry
Figma’s Auto Layout supports individual padding values (top, right, bottom, left). Most automated tools handle this correctly, but some shortcut to padding: X shorthand even when the values differ — producing visually wrong output.
5. Gap with auto-resizing items
When a parent has a gap value and contains items that resize automatically (HUG sizing), the spacing calculations can produce unexpected results in certain browsers. Modern Flexbox handles this well, but legacy browser support adds complexity.
What Good Conversion Tools Get Right
A well-designed Figma-to-Flexbox converter handles all of the above correctly. Practically, that means:
- Recursive processing that generates clean Flexbox contexts at each level
- Per-axis sizing logic that maps FIXED/HUG/FILL to the correct CSS
- Correct child-level flex-grow and align-self based on layoutGrow and layoutAlign
- Graceful fallback to absolute positioning for non-Auto-Layout frames
- Detection of contradictory sizing (HUG parent with FILL child) and sensible resolution
The output should be readable Flexbox code that a developer would want to inherit. Generic class names, nested divs with inline styles, or fallback to absolute positioning when Flexbox would be cleaner — these are signs the tool isn’t doing the harder work.
A Practical Workflow
If you’re hand-coding Figma to Flexbox, here’s a workflow that maps cleanly to the Auto Layout structure:
- Identify each Auto Layout frame and decide which CSS class will represent it
- Map layoutMode to flex-direction for each frame
- Map sizing modes to width/height/flex-grow per axis
- Apply alignment via justify-content and align-items
- Handle children with non-default behavior using flex-grow and align-self
- Recurse into nested frames, starting again from step 1
This is mechanical work. If you’re doing it across 10-20 frames per project, it’s exactly the kind of work that automated tools can save you 60-70% of the time on — leaving you to focus on the responsive behavior, animations, and brand-specific polish that automation can’t deliver.
Conclusion
Figma Auto Layout maps cleanly to CSS Flexbox for the common cases. The mapping is so direct that most experienced developers can write the CSS manually, but the time required adds up across a real project.
The harder cases — nested structures, mixed sizing modes, layoutGrow with contradictory parent settings — are where automated conversion either delivers real value or falls apart. Choosing a tool that handles these cases correctly is what determines whether you save time or spend it cleaning up.
If you’d like to see how the mapping plays out on a real Figma file, EspritCode offers a free plan with 5 conversions per month. It’s built specifically to handle the edge cases above, so the output is clean Flexbox code rather than absolute-positioned divs.
Related Reading
For more on Figma-to-code workflows and tool selection, these articles complement the technical content above:
- How to Convert Figma to HTML/CSS in 2026: A Complete Guide for Web Developers — A broader overview of the three main approaches to Figma-to-code conversion.
- Figma to Code Tools Compared: Which One Is Right for You in 2026? — A detailed comparison of major automated conversion tools.