CSS Grid and Flexbox: comparison in practice. Layout on Grid in CSS. Complete guide and reference. Flexbox solution

Danny Markov

The design is quite simple - it consists of a center-aligned container, inside of which we have a header, a main section, side panel and a basement. Here are the main "tests" we should run while keeping the CSS and HTML as clean as possible:

  1. Place four main sections of the layout.
  2. Make the page responsive (the sidebar falls below the main content on small screens).
  3. Align header content - left navigation, right button.

As you can see, for the sake of comparison, we kept everything as simple as possible. Let's start with the first test.

Test 1: Laying out page sections

Flexbox solution

Add display: flex to the container and set the direction child elements vertically. This positions all the sections underneath each other.

Container ( display: flex; flex-direction: column; )

Now we need to make sure that the main section and the sidebar are located next to each other. Since flex containers are usually unidirectional, we need to add additional element.

We then set this element's display: flex and flex-direction to the opposite direction.

Main-and-sidebar-wrapper ( display: flex; flex-direction: row; )

The last step is to set the dimensions of the main section and sidebar. We want the main content to be three times as wide as the sidebar, which is easy to do with flex or percentages.

As you can see, Flexbox did everything well, but we also needed quite a lot of CSS properties plus an additional HTML element. Let's see how CSS Grid will work.

CSS Grid solution

There are several options for using CSS Grid, but we will use the grid-template-areas syntax as the most suitable for our purposes.

First we'll define four grid-areas, one for each section of the page:

header ( grid-area: header; ) .main ( grid-area: main; ) .sidebar ( grid-area: sidebar; ) footer ( grid-area: footer; )

Now we can set up our mesh and define the location of each area. The code may seem quite complicated at first, but once you become familiar with the grid system, it becomes easier to understand.

Container ( display: grid; /* Define the size and number of columns of our grid. The fr unit works like Flexbox: the columns divide up the available space in the row according to their values. We will have two columns - the first is three times the size of the second. */ grid-template -columns: 3fr 1fr; /* Link the previously made areas to places in the grid. The first line is the header. The second line is divided between the main section and the sidebar */ grid-template-areas: "header header" main sidebar" "footer footer"; /* The spacing between grid cells will be 60 pixels */ grid-gap: 60px; )

That's all! Our layout will now follow the above structure and we've set it up so that we don't have to deal with margin or padding.

Test 2. Making the page responsive

Flexbox solution

This step is strictly related to the previous one. For a Flexbox solution, we will have to change the flex-direction and adjust the margin.

@media (max-width: 600px) ( .main-and-sidebar-wrapper ( flex-direction: column; ) .main ( margin-right: 0; margin-bottom: 60px; ) )

Our page is fairly simple, so there's not a lot of work in the media query, but a more complex layout would require a lot of rework.

CSS Grid solution

Since we've already defined grid-areas , we just need to redefine their order in the media query. We can use the same speaker setup.

@media (max-width: 600px) ( .container ( /* Align grid areas for mobile layout */ grid-template-areas: "header header" "main main" "sidebar sidebar" "footer footer"; ) )

Or we can redefine the entire layout from scratch if we think this solution is cleaner.

@media (max-width: 600px) ( .container ( /* Convert the grid to a single-column layout */ grid-template-columns: 1fr; grid-template-areas: "header" "main" "sidebar" "footer"; ) )

Test 3: Aligning Header Components

Flexbox solution

We have already done a similar layout with Flexbox in one of our old articles -. The technique is quite simple:

Header ( display: flex; justify-content: space-between; )

The navigation list and button are now aligned correctly. All that remains is to place the items inside