Published 2026-08-05
Auto Layout in Figma: How It Maps to CSS Flexbox (and When You Still Need Grid)
If you've ever opened a Figma file and seen "Auto Layout" turned on for a frame, you've already been looking at something very close to Flexbox — Figma's designers borrowed the mental model on purpose. Understanding the mapping isn't just trivia: it's what lets you go from a design file to working CSS without guessing at every spacing value by eye.
What Auto Layout actually controls
Auto Layout is Figma's way of making a frame behave like a real layout container instead of a group of absolutely positioned shapes. Turn it on for a frame and you get a handful of properties to configure:
- Direction — whether children stack vertically or horizontally.
- Spacing / gap — the fixed distance between each child element.
- Padding — the space between the frame's edge and its children, settable per side.
- Alignment — how children line up along and across the layout axis.
- Resizing behavior — whether the frame and its children hug their content, fill available space, or stay a fixed size.
None of this is arbitrary. Each property exists because it corresponds to something a real layout engine needs to know — which is exactly why it maps so cleanly to CSS.
The direct mapping to Flexbox
| Figma Auto Layout | CSS Flexbox equivalent |
|---|---|
| Direction (vertical/horizontal) | flex-direction: column / row |
| Spacing between items | gap |
| Padding | padding |
| Primary axis alignment | justify-content |
| Counter axis alignment | align-items |
| Hug contents | width: fit-content / height: fit-content |
| Fill container | flex: 1 or width: 100% / height: 100% |
| Fixed size | explicit width / height |
Once you see the table, it's clear why Auto Layout feels intuitive to anyone who already knows Flexbox — and why Flexbox feels intuitive to designers who started in Figma. They're describing the same box model with different names.
Where hand-translation goes wrong
Even with a clean mapping, developers reproducing Auto Layout by hand tend to trip on the same handful of details:
- Mixed alignment gets flattened. Figma lets individual children override the group's alignment; it's easy to eyeball this and apply one
align-itemsvalue to everything, losing per-child overrides that needalign-self. - "Hug" vs "fill" ambiguity. A frame set to hug its contents looks identical to a fixed-width frame at a single viewport size, but behaves completely differently once content or screen size changes. Guessing wrong here is a common source of layouts that break on real content.
- Gap support gets skipped. Some developers still reach for margin tricks instead of
gap, inherited from older Flexbox advice — unnecessary now thatgaphas solid browser support, and it reintroduces the exact spacing bugsgapwas meant to fix. - Nested Auto Layout frames become nested flex containers without a plan. Each nested frame is its own flex context, and a literal one-to-one translation can produce more wrapper elements than the layout actually needs.
- Padding on the wrong element. It's easy to apply a frame's padding to a child instead of the container, which throws off gap-based spacing between siblings.
When Flexbox isn't the right target — reach for Grid
Auto Layout is a single-axis model: it's very good at rows and columns, including nested combinations of them. But some designs are genuinely two-dimensional, and forcing them into nested Flexbox produces code that's harder to maintain than the design ever was. Reach for CSS Grid instead when you see:
- A layout where items need to align on both rows and columns simultaneously — think card grids, dashboards, or image galleries.
- Explicit "this spans two columns" or "this spans two rows" behavior, which Grid handles natively with
grid-column/grid-rowand Flexbox can't express directly. - Designs where the number of columns should respond to available width (
repeat(auto-fit, minmax(...))) rather than to a fixed breakpoint list. - Overlapping or layered regions within a shared grid, which is straightforward with Grid's placement system and awkward with Flexbox.
A good rule of thumb: if a Figma frame's Auto Layout only ever nests in one direction at a time, Flexbox is a faithful translation. If you find yourself building a grid of Auto Layout frames to fake row-and-column alignment, that's usually Figma's UI compensating for the fact that it doesn't have a native two-dimensional Grid layout mode — and it's worth generating actual CSS Grid instead.
How MarkupGen handles this automatically
This mapping is well understood, but doing it correctly on every frame, every gap value, and every nested container in a real design file is tedious — and it's exactly the kind of repetitive translation work MarkupGen is built to remove. The workflow is four steps: export the frame from Figma using the companion plugin, which pulls the structure, styles and images straight into your workspace; MarkupGen's AI builds HTML and CSS from that actual structure, automatically mapping Auto Layout's direction, gap, padding and alignment onto an equivalent Flexbox structure instead of leaving it to manual guesswork; you refine content, fonts and layout visually in an in-app editor; then you export the final package. Responsive breakpoints are generated automatically from the design's resizing constraints, and you can choose the output format — vanilla HTML/CSS, Tailwind CSS, or React components — depending on your stack. Every export also gets an automatic AI quality score, so you can see at a glance whether the generated markup is ready to ship. The output favors clean, semantic HTML without unnecessary nested <div>s, which matters for maintainability as much as for SEO.
Try it on your own design
Understanding the Auto Layout-to-Flexbox mapping makes you faster at reviewing generated code and better at spotting where a design genuinely needs Grid instead. If you'd rather skip the manual translation entirely, try MarkupGen on your own Figma file for free, or read the full Figma-to-HTML conversion guide for the end-to-end workflow.