Throughout my career as an engineer, I have been given a countless amount of specs, design documents and Figma files to bring ideas to life. I have attended handoffs, kickoffs, design critiques, you name it. Something I noticed out through the years is more often than not, it feels like designers and developers are talking about the same thing while actually having fundamentally different mental models. And here is where the friction between these two disciplines comes into play.
The canvas vs. the browser
A designer has a canvas, and moves around stuff in this space. They can put an element wherever they want, move it around, resize it. This is quick, easy, fun and provides them with the creativity that a designer needs.
But, the browser doesn’t work like that. A browser organizes the elements in stacks. These elements have relationships, they take up space, and their position can change depending on the items around them.
A design to an engineer is a snapshot in a particular size screen, and our job usually is to find the correct rules that produce this result and interpolate this to different sizes.
The interesting part is that the gap between these two mental models isn't actually as big as it might seem. Design tools have started to give designers many of the same or similar concepts that developers use to build layouts. Figma has an "Auto Layout" option, for example, which is very close to the way we think about CSS Flexbox. This helps the designers and developers to find a common vocabulary and collaborate more.
Auto Layout → Flexbox
If you have worked with CSS for a while, you probably know about Flexbox. It has already been available to developers for the last decade.
The basic idea is simple: you have a container with a number of children, and you want to describe how those children should be laid out and how they should use their available space. Instead of telling the browser where each element should go, you describe the relationship between them.
Imagine having multiple buttons inside a container. The moment you instruct that this container is a flex container, I can say that these buttons should sit next to each other, have a gap between them and be aligned to the center. If the container gets wider, the layout can adapt. If one button becomes larger because its label changes, the others can respond accordingly.
Figma has something very similar: Auto Layout! If you have used Auto Layout in the past, you already understand many of the concepts behind Flexbox. You have a container and you decide whether its children are arranged horizontally or vertically. You define spacing and alignment. You decide how the container should behave when its contents change, and how the children should use the available space.
And just like Figma allows you to nest Auto Layout frames, CSS allows you to nest flex containers.
Each of those containers can have its own layout rules. One can arrange its children vertically, another horizontally, and another might allow one child to take up all the remaining space.
The closer the mental model in Figma is to the mental model in the browser, the less translation is required between the two.
When one dimension isn't enough → CSS Grid
CSS Flexbox solves many problems for frontend development, but it still is 1-dimensional layout. What that means is that it handles the items in a single main axis (something like a single row or column).
In many problems we solve one dimension is not enough. So we have a CSS Grid, which is a container in 2 dimensions. Think about a dashboard, a photo gallery, or a page with multiple sections that need to line up across both rows and columns. Now we're not only just asking “how should these things sit next to each other?”, but also “how should these things relate to the structure of the entire layout?”
The easiest way to picture this, it is a grid of cells, something like a table, but unlike a table, these cells aren't tied to the content in a particular row or column. We can define the structure of the layout and decide how elements should span across it.
A designer might look at a Figma canvas and see a beautiful asymmetric layout: one large image spanning two columns, a group of cards underneath, and a section that stretches across the entire page. A developer doesn't need to reproduce that with a collection of arbitrary pixel positions, but they can describe the underlying structure.
This gives designers something useful to think about when creating layouts. That doesn’t mean that grid is the answer to all the problems, we can mix and match those tools to achieve the result.
The important thing is for the designer and developer to work closely with each other. One can help each other, by strong communication and understanding of each others language. It’s not about just handing off designs anymore, but more about thinking these systems and the interaction needed to achieve useful results.
Designing for change → responsive layouts
A design might look as a static snapshot to a developer. It works in a very defined size. A Figma file might give us a desktop design and a mobile design, but the browser has to deal with everything in between.
A breakpoint is essentially the point where the current layout stops making sense. In CSS we use media or container queries that help us to determine the perfect layout for each screen size and all the steps in between.
Flexbox and Grid already give us layouts that can respond to changes in available space. A container can grow and shrink, items can wrap, and columns can adapt without us defining what should happen at every screen width.
Instead of designing only “desktop” and “mobile”, think about the hierarchy of the interface and how that hierarchy should respond when space becomes constrained. Typography is a good example. A heading doesn't necessarily need one font size on desktop and another completely different font size on mobile. CSS gives us tools like clamp() that allow a value to scale within a defined range.
The goal isn't to create a collection of screenshots that the developer has to somehow connect together. It's to define enough rules and constraints that the interface can behave sensibly in the space between those screenshots.
The container matters → container queries
The responsive design can be elevated even more with container queries.
We're probably more familiar with media queries in development, we use it for ages to create responsive designs. A media query looks at the viewport and asks how much space does the browser window have? Based on that, we can change the layout.
But CSS gives us cool tools these days, and we can be more explicit on our responsive designs. Container queries ask a different question: How much space does this component actually have?
Imagine we have a card component. On a large screen, the card might have enough space to show an image next to its content. But the same card could be placed inside a narrow sidebar, where that layout no longer makes sense.
With a media query, the component would respond to the size of the screen. With a container query, it can respond to the space that is available to the component itself.
Beyond the handoff
The goal isn't for the designers to become developers, or vice versa. A designer doesn't need to know how to write grid-template-columns, and a developer doesn't need to know how to create a perfect Figma component.
The goal is to understand enough of each other's world to share a mental model of what's being built. A good handoff isn't just a Figma link with a list of measurements, colors, and font sizes. Yes, all of these are useful, but they merely describe the result.
What matters more is understanding the intention behind the design. The bridge between design and development isn't the handoff, but a shared mental model.
Top comments (0)