CSS Grid or Flexbox? How to pick between the two CSS layout systems
When should you use Flexbox or Grids?
Today, we can’t talk about designing web pages in CSS without mentioning its two main layout-centered modules, CSS grid and flexbox. The introduction of flexbox and CSS grid replaced the age-old “hacks” developers previously used to create page layouts and position and align components. It gave us a straightforward way to carry out these tasks without unnecessary complexities.
However, with the roles they are intended to play being almost the same, there is still a lot of debate surrounding the best occasions to use each layout system in a web page design. The answer to this question is not easy to determine. Like many things in CSS, the final verdict depends a lot on the developer’s personal preference. But it shouldn’t stop us from gaining a general idea about what kind of use cases fits better against each layout system’s characteristics.
We can start to build a clearer picture of when to use flexbox and grid by first understanding the main differences between the two modules.
One-dimensional flexbox vs two-dimensional grid
According to MDN documentation , the main difference between flexbox and grid is this:
“The basic difference between CSS Grid Layout and CSS Flexbox Layout is that flexbox was designed for layout in one dimension—either a row or a column. Grid was designed for two-dimensional layout—rows, and columns at the same time.”
With the flexbox, we can only control how elements are placed along a single axis through the flex-direction property. Even though the layout can expand two dimensions when the “wrap” option is set, we have no control over how elements position along the second axis. It’s why flexbox is recognized as a one-dimensional layout system in CSS.
The following example shows how the flexbox controls element-positioning along the horizontal axis (rows) using the flex-wrap property. Even though “wrap” allows elements to overflow to the next row, flex doesn’t provide us a way to define their vertical positions (columns).
On the other hand, grid layout allows us to control element placement along both vertical and horizontal axes. We can go as far as defining the exact position of each grid item using row and column numbers. Therefore, we can call the CSS grid a two-dimensional layout system without hesitation.
However, flexbox being a 1D layout system doesn’t stop it from being a good fit for creating some 2D layouts. Flexbox can easily support unique designs that expand multiple rows and columns with the help of wrap. Similarly, CSS grid being a 2D system shouldn’t automatically eliminate it from 1D layout designs.
Content-driven flexbox vs layout-driven grid
Identifying the driving factor behind each module’s layout formation is the best way to understand the functional difference between flexbox and grid. In this categorization, flexbox takes a content-driven approach while the grid takes a layout-driven one.
The height and width of a flexbox item largely depend on the content added to it. It can grow and shrink as needed to accommodate the content in the provided space. We can especially observe this behavior of the flexbox when wrap is allowed.
This quality of the flexbox makes it unpredictable in terms of how the final layout of the design turns out. It allows flexbox to determine the item count and positioning in each row or column (depending on the flex-direction) independently of how other rows and columns behave. It makes flexbox designs more flexible when adapting to available space. With properties like flex-grow and flex-shrink, we can also control how flex items should behave when there’s additional or reduced space.
In the following example, we can clearly see how flexbox arranges its layout based on the content inside each item.
Compared to flexbox, CSS grid follows a more rigid, layout-driven approach for item placement. It requires us to define the basic layout precisely using the number of columns and/or rows with grid-template-rows and grid-template-columns properties. Then, it strictly follows the created grid lines when calculating each item’s height and width.
Since the CSS grid’s primary focus is on the layout, the final outcome of a grid-based design is easily predictable, unlike with the flexbox. Grid also leaves room to introduce some flexibility to the design through grid-auto-rows, grid-auto-columns, and grid-auto-flow properties. It enables the grid to fluidly add more rows or columns to accommodate all available items.
Here’s what we get when we use CSS grid to create a layout for the elements in the previous flexbox example.
As you can see, the grid follows a more rigid layout with strict rows and columns in the two-dimensional space to give us a more predictable, orderly outcome compared to the flexbox.
When to use flexbox
With these differences between flexbox and grid in mind, let’s look at when we should use flexbox to create layouts.
Most commonly, flexbox is used to layout small components and align content. Here are a few examples of such instances.
Vertically and horizontally centering content
The introduction of the flexbox gave frontend developers a straightforward way to center content, especially vertically, in CSS. We can use a combination of justify-content and align-self/align-content properties to center a flexbox item like this.
Pushing the footer to the bottom
We can make the footer of a web page or another component stick to the bottom by properly setting the flex-grow property. In the following example, we have set the flex-grow of the content element to 1, allowing it to take all the excessive space inside the flex container. This automatically pushes the footer to the bottom.
Creating inline forms or menus
Both inline forms and menus consist of inner elements that need to be aligned along a single direction. Flex lets us build these types of responsive components with ease.
So far, all the examples we discussed used flexbox for designing small UI elements. But we can use flexbox for creating larger layouts, sometimes entire web pages, if the design follows a content-driven principle. When different items in the layout have content-dependent heights and widths, which you may not be able to predict beforehand, using flexbox to design the layout makes more sense than relying on the CSS grid.
When to use CSS grid
CSS grid is best used when you want to build UI components with precise layouts or element placements. In practice, CSS grid is commonly used for creating entire page layouts with headers, footers, sidebars, etc. Layouts that require intricate grid systems such as 12-column-grid or asymmetric designs are comparatively easier to build with CSS grid than the flexbox.
Grid is also a good fit for designing smaller, one-dimensional components when they require precise element placements.
In the following example, we will define the rough layout of a web page with the help of the grid-area property.
Creating layouts with overlapping elements
Since CSS grid allows us to define an element’s exact position, designing layouts with overlapping components becomes a simple task. In comparison, if we try to implement this flexbox, we’ll have to rely on hacks like setting negative margins, absolute positioning, or transforms.
Wrapping up
CSS grid and flexbox are the two newly introduced layout modules in CSS. Even though their functionality overlaps with each other to a certain extent, both CSS grid and flexbox have unique qualities that make them well-suited for designing certain types of layouts. Today, we discussed the fundamental differences between grid and flexbox to understand when to use these two modules in a website design.
Other than the use cases discussed here, we often find problems that aren’t as straightforward when it comes to choosing between CSS grid and flexbox. Deciding which module to use in such situations largely comes down to your past experiences and personal preference. As you experiment and practice using these two modules, it’ll become easier to determine which module between flexbox and grid fits the best with a particular use case.
Source: livecodestream