UI design tools are becoming better at translating design to code, which means that more of the choices you make as designers have an impact on the development part of the product process.
The Figma feature that has the biggest impact is auto layout, which translates to CSS flexbox code for web development. Grid layout can also be used in certain scenarios, but hardly any UI design tools support it at the moment.
In this article, you’ll learn what flexbox and grid layout do, the benefits of using both to develop websites, and the ways you can mockup designs that’re Flexbox and Grid Layout friendly.
Flexbox (or “flexible box module”) enables developers to code horizontal/vertical layouts in a smart way where the dimensions of the elements involved aren’t necessarily known. Overall, it requires less code (that’s more manageable) compared to legacy techniques, especially when it comes to horizontal layouts since websites are naturally vertical (sort of).
As you can imagine, flexbox is incredible for responsive design too, since it’s more dynamic/rule-based than static. When you’re using auto layout in Figma, you’re essentially using flexbox. In addition, dev mode is translating your auto layouts to flexbox code. How cool is that?
In order to truly understand the benefits of Flexbox and why design is becoming more entwined with code it’s best to actually compare the resulting code with and without flexbox/auto layout.
Consider two rectangles side-by-side, no auto layout. Now first, dev mode doesn’t produce the code needed to display them horizontally because it doesn’t understand (without auto layout) the relationship between them. Without this code, the natural behaviour is for them to stack vertically. In fact, here’s what a website looks like without any styling at all:
So to establish this relationship, you’d need to wrap the rectangles in a frame (or in code terms, a flex container) that has auto layout activated, where the default behaviour is to then display child elements horizontally. This causes dev mode to produce the following code:
#container { display: flex; flex-direction: horizontal; }
Dev Mode also produces a gap: 100rem;
that gives you the 100-pixel spacing between the two rectangles. This CSS property only works with flexbox and grid layout, so again, you get nothing if you choose not to use auto layout.
And finally, dev mode produces padding: 100rem;
to create 100-pixel spacing around the frame. This CSS property isn’t exclusive to flexbox or grid layout, but nonetheless won’t be produced by dev mode if auto layout isn’t used. Without auto layout, you don’t really get any layout code at all:
So that covers direction.
But now how do you make this layout responsive in some way? The traditional method is to create multiple artboards (or in Figma terms, top-level frames) with each one showing what the design looks like at a different size, but I’m sure I don’t need to tell you what a logistical nightmare this would be (even more so if the rectangles/columns were to have some content, of course):
Regardless, this method doesn’t yield any layout code either (not even media query code, which is the web dev equivalent of having multiple top-level frames). Here’s what media query code looks like:
@media (max-width: 575px) { /* do something */ } @media (min-width: 576px) and (max-width: 767px) { /* do something else */ } @media (min-width: 768px) { /* do something else */ }
This just isn’t ideal. Especially not when you can avoid it.
Instead, what you could do is embrace fluidity, even if it’s combined with some static elements. As mentioned before, this means activating auto layout on the container (shift + A
, or click on “auto layout +” in the “design” panel):
Now you simply need to define the behaviour of each column. You could, for example, set the “W” of the left column to “360” and the “W” (or “horizontal resizing” underneath “W”) of the right column to “fill container” (meaning that it fills the remaining space):
Additional top-Level frames/media queries could still be required depending on what you’re trying to achieve, but nonetheless, auto layout awards you with a terrific one-liner for the column on the right — align-self: stretch;
.
Auto layout/flexbox is all about relationships, where all of the elements involved are aware of each other and respect each other’s boundaries. It’s algebra, essentially — try to think of the right column as r
, the left column as 360
, and the flex container as 1080
.
You’re left with r = 1080 - 360 - 100
(100
is the spacing).
But what if the container was responsive too? Meaning, “fill container” instead of 1080
? Well, first, in order to access flexbox features such as “fill container”, its parent would also require auto layout.
So now the equation is r = c - 360 - 100
, where if c = 1080
then r = 620
, but in reality c
could be anything and that’s why you end up with the beauty below at the end of it all:
Simple but elegant, and with free code.
You could even “add min width…” or “add max width…” (to access these, click on the “W” dropdown) to any of the layers to define some restraints. This gives you even more code (min-width: x;
and max-width: x;
) that again is only available to layers with auto layout or that are nested within Auto Layouts.
So if you were to set the left column “Add max width…” to “360” and use “fill container,” this would make the columns 50/50 until the left column reaches 360, in which case it would stop stretching.
All of this using just one top-level frame!
There’s another auto layout option called “hug contents,” however, it’s impossible for the right column to expand to fill the remaining space in the container while the container shrinks to fit the size of its contents. Even though this is clearly a paradox, it’s easy to become lost in the logic when auto layout-ing everything. That being said, I believe that it’s easier to reconcile the logic than it is to manage multiple top-level frames. Thinking of it in terms of algebra helps significantly.
When you need row and/or column-like layouts, grid layout is more suitable. I say “row and/or column-like” because HTML table code (<table>...</table>
) is still the only semantic/correct way to code actual tables, but that’s a conversation for another time. For now, think of grid layout as being suitable for, say, cards:
In terms of CSS code, you’d need something like this:
#container { display: grid; grid-template-columns: repeat(3, 1fr); }
1fr
means 1 fraction (so basically, 3 equally spaced columns).
Nothing too crazy so far, but I’m sure you’re wondering…why not use flexbox, since flex items can be wrapped? The reason is that wrapping can be clumsy. For example, you could very easily wind up with something like this misaligned monstrosity:
On the upside, flexbox has alignment options. You can see this for yourself by experimenting with the alignment settings in the “auto layout” section of the “design” panel (keep in mind that you can combine alignments by nesting frames with auto layouts).
And naturally, these produce CSS Flexbox properties too:
align-items: flex-start | center | flex-end | stretch | space-between; justify-content: flex-start | center | flex-end | stretch | space-between;
(Double-click on the alignment box for space-between
).
So think of flexbox as having better alignment options as well as being more flexible with its sizing options, and grid Layout as having better, well…grid options. For example, developers could add grid-row: span 2;
to the first grid item to create something like this:
Sometimes, either one can do the job though!
Unfortunately though, Figma doesn’t support grid layout yet (well, not natively anyway).
There are two main tools you can use to get grid layout codes for your designs: Penpot and Anima.
Penpot isn’t as well known as other UI design tools, but it has an excellent rating of 4.62/5 according to the 2023 Design Tools Survey. Its newest feature is grid layout support, and as far as I know this is the only UI design tool that offers this. Also, it’s surprisingly comparable to Figma, so it might be worth taking a look. Did I mention that it’s free/open-source too?
If you really wanted to generate grid layout code from Figma mockups (understandable, since it’s the most popular UI design tool by a huge margin), the Anima plugin for Figma is worth a look (specifically, Anima’s AI design-to-code feature). Although it’s a design-to-code solution, it’s not as overzealous as most design-to-code features. Plus, it’s not what some would consider a no-code feature either, since developers are expected to build upon the resulting code, which is easy to do.
On the design side of things, your grid should look like this:
After that, run the Anima plugin from Dev Mode, and then activate the “Use CSS grid” setting (“presets” > “responsive design”). Don’t worry, Anima does a decent job of knowing when to actually use grid layout and when to stick with flexbox:
Flexbox and grid layout are incredible, and while you realistically only have Figma’s auto layout at your disposal to create flexbox friendly designs, Penpot’s support for grid layout signals that you might see other UI design tools following suit. Only then can you truly have a moderate design-to-code solution, since no-code tools are typically quite overzealous while coding from scratch is typically more time-consuming.
The main takeaway here is to use auto layout — not everywhere, just where it makes sense (although you’ll likely discover that it makes sense in most places). This’ll provide developers with useful, dynamic layouts rather than not-very-useful coordinates.
Got a question? Drop it into the comment section below.
And thanks for reading!
As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording everything that happens in your web app, mobile app, or website. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.
Modernize how you debug web and mobile apps — start monitoring for free.
LogRocket lets you replay users' product experiences to visualize struggle, see issues affecting adoption, and combine qualitative and quantitative data so you can create amazing digital experiences.
See how design choices, interactions, and issues affect your users — get a demo of LogRocket today.
Nostalgia-driven aesthetics is a real thing. In this blog, I talk all about 90s website designs — from grunge-inspired typography to quirky GIFs and clashing colors — and what you can learn from them.
You’ll need to read this blog through and through to know what’s working and what’s not in your design. In this one, I break down key performance metrics like task error rates and system performance.
Users see a product; designers see layers. The 5 UX design layers — strategy, scope, structure, skeleton, and surface — help build UIs step by step.
This blog’s all about learning to set up, manage, and use design tokens in design system — all to enable scalable, consistent, and efficient collaboration between designers and developers.