Previously, a frontend developer would jump through hoops to float and clear elements, or even use javascript just to balance elements on a webpage for each device. Today, with a mobile first approach, your CSS may now encompass flex and grid to control elements within a website or web application’s layout. The primitive era (or so I call it) of frontend development required rigging your elements in tables, utilizing in-line blocks, a sprinkle of javascript to clean up elements and spacing, and all sorts of positions and floats in order to effectively depict a design. The Old World techniques may have been effective, but were highly complex and heavy in code.

To simplify both the creation and maintenance of websites and web applications, responsive layout models were created. Among the most popular are Flexbox, CSS Grid, and Bootstrap, each of which are widely supported across most platforms and browsers. Full open-source toolkits such as Bootstrap have come a long way and are helpful, but at the end of the day if the task of the frontend developer is to create their own base CSS, it’s important to know how to display a layout with these new tools. The project’s performance and speed will increase by cutting out all the complex code from the days of yore.

What’s the Difference?

The most important thing to know is that flexbox is one-dimensional, while CSS Grid is two-dimensional. Flexbox lays out items along either the horizontal or the vertical axis, so you have to decide whether you want a row-based or a column-based layout. A flex layout can also wrap in multiple rows or columns and flexbox treats each row or column as a separate entity, based on its content and the available space.

On the other hand, CSS Grid lets you work along both axes. Grid allows you to create two-dimensional layouts where you can precisely place grid items into cells defined by rows and columns.

This is how W3C wants us to use flexbox and grid, however practice frequently overrides theory and not everyone is fan of the one-dimensional vs. two-dimensional narrative. In reality, we can create two-dimensional layouts with flexbox (due to its wrapping ability) and one-dimensional layouts with CSS Grid (due to its auto-placement ability).

Flexboxes

While flexbox can make rows and columns in the sense that it allows elements to wrap, there’s no way to declaratively control where elements end up since the elements merely push along a single axis and then wrap or not wrap accordingly. They do as they do, if you will, along a one-dimensional plane and it’s because of that single dimension that we can optionally do things, like align elements along a baseline — which is something grid is unable to do.

.element {
display: flex;
flex-flow: row wrap;
align-items: baseline;
justify-content: space-evenly;
}

Grids

CSS Grid focuses on precise content placement. Each item is a grid cell, lined up along both a horizontal and a vertical axis. If you want to accurately control the position of items within a layout, CSS Grid is the way to go.

.element {
display: grid;
grid-template-columns: 1fr 3fr 1fr;
grid-template-rows: 200px auto 100px;
grid-template-areas:
"header header header"
". main sidebar"
"footer . .";
}

Most of the layout is defined within the parent with grid-template-columns assigning the standard width of the column. In the example above our middle column is three times larger than the others. The grid-template-rows sets the widths for each row. The grid-template-areas is where we establish the cells in the grid and assign them names. Each child element may then have a grid-area assigned and it will be placed within the grid on render.

.child-01 {
grid-area: header;
}
 
.child-02 {
grid-area: main;
}
 
.child-03 {
grid-area: sidebar;
}
 
.child-04 {
grid-area: footer;
}
 1
 2
 3
 4

Gaps

Grid CSS is mostly defined on the parent element. With a flexbox approach, most of the layout’s properties beyond the basics are defined on the children. Both allow the property gap which defines the space between the children elements. Not all devices currently work with this so responsively we can add margins and padding to elements as well in conjunction with gaps. Frontend developers do not have to rely solely on gap. The parent element should have properties assigned to control the alignment and justification of its children. The align-items and justify-content properties suit this purpose as seen above and below.

The property flex allows the control to grow and stretch an element within the flexbox and assign maximum widths. Setting  flex: 0 0 100%  will stretch the element across the entire parent and wrap the rest of the children below. Flex of 1 allows the item to stretch and fill the space up to the gaps.

.element {
display: flex;
flex-flow: row wrap;
align-items: center;
justify-content: center;
min-height: 400px;
gap: 1rem;
}
 
.child-01,
.child-03 {
flex: 0 0 25%;
}
 
.child-02 {
flex: 1;
}
 1
 2
 3

As for grids, setting the grid-gap will space the cells evenly throughout the entire grid.

.element {
display: grid;
grid-template-columns: 1fr 3fr 1fr;
grid-template-rows: 50px minmax(200px, 2fr) 100px;
grid-template-areas:
"header header header"
"main main sidebar"
"footer footer footer";
grid-gap: 0.5rem;
}

Performance & Clean Code

The hot topic debate in the CSS world is currently which to use, Grid CSS or Flexbox? The answer depends solely on the design and the frontend development approach needed to render the look required. Understanding the basic principles of both and disregarding the fundamental ideas behind them, we can utilize them in real world approaches that will cut down on the bulky code from years passed. With this trim in code comes overall performance enhancement as well as speed with a quick contextual render for an optimal user experience.