CSS Layouts

CSS Grid vs Flexbox

‘Red’ by Mark Rothko & ‘Grande Composizione A Con Nero, Rosso, Grigio, Giallo e Blu’ by Piet Mondrian

The way we organize information can have a significant impact on a user’s ability to understand it. This means that the ability to layout information in a way that the user can easily digest is extremely important.

The two paintings above for example, illicit two very different responses from the viewer. Because of the way those colored rectangles are laid out on the canvas they become vastly different artworks and we experience them in different ways.

‘Red’ by Mark Rothko

The Rothko consists of three rectangles contained within the frame. The rectangles are laid out in a single direction (vertically) and their position can be defined based on their relationship to the frame and to each other. This method of layout is a great analogy for how Flexbox works.

‘Grande Composizione A Con Nero, Rosso, Grigio, Giallo e Blu’ by Piet Mondrian

The Mondrian’s layout is a bit more complicated. Black lines are used to divide the canvas into a grid and then rectangles are placed onto that grid , so that their sides align to the grid lines. This allows them to be aligned both vertically and horizontally at the same time. This is a perfect analogy for CSS Grid.

Flexbox is used to layout elements in a single direction, it excels at dynamically scaling and aligning elements within a specific component.

Grid layouts function in two directions (think rows and columns) and are best used for laying out whole pages or sections of a page that require two-dimensional layout.

So far we’ve been focusing on the differences between CSS Grid and Flexbox, but they have many similarities as well.

  • Both systems work by applying a combination of CSS rules to both the parent element (or container) and its child elements (or items).
  • Both are well supported by modern browsers.
  • Both work by allowing the parent element to control the position of its child elements.
  • In both cases the parent element only has control of its direct children.

How To Use Flexbox

Container Properties:

The first step is to designate your container element. Let’s do this by giving our parent element the class .container and giving our class some rules.

.container {   
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}

Now that we have given .container a few rules let’s talk about what they actually do.

display designates the container element and sets the context it will use to position its children.

flex-direction sets the orientation of the elements within the container. It has four options:

  • row places the items in order from left to right horizontally.
  • row-reverse places them from right to left.
  • column places the items vertically from top to bottom.
  • column-reverse places them from bottom to top.

flex-wrap will allow the items in the container element to wrap onto a second line if they can’t fit in one. It’s options are wrap , nowrap (the default), and wrap-reverse which will allow items to wrap onto a second line from bottom to top.

justify-content defines how the browser distributes space around content items inside the container along its main axis.

align-items defines how the browser distributes space around content items inside the container along its cross axis. Individual items can override the alignment set by the container through the use of align-self .

Item Properties:

Each item in our container element will now be positioned according to the CSS rules specified. We can gain access to more granular control of these elements by giving them their own CSS rules.

By default items in a flexbox container are placed in the order they are written in the source code. However, by assigning order: x to a specific element, you can specify the order in which it is placed.

flex-basis defines the default size of the element before any negative space is distributed.

How To Use Grid

Container Properties:

Just like with Flexbox, we start by defining some rules for our container object. First, display is set to grid, then we need to define grid-template-columns and grid-template-rows, both of which take a list of measurements that represent the space between the grid lines. Optionally, you can give the gridlines names in square brackets (as shown below) if you don’t name them the grid lines will be given number values.

.container {
display: grid;
grid-template-columns: [one] 25% [two] 50% [three] 25% [end];
grid-template-rows: [a] 25% [b] 25% [c] 25% [d] 25% [end];

First we set the display to grid, then we need to define our columns and rows. we do this by setting rules for grid-template-columns and grid-template-rows . These properties define names for the columns and rows in our layout as well as the amount of space each row or column takes up. If you omit the names when defining these rules, they will be assigned numerical names for you.

You can use these properties to define your grid in anyway you want, making it an extremely versatile tool.

Item Properties:

Now that we have our grid set up, we need to position our items inside the container. We do this using four CSS properties:

#item-one {
grid-column-start: two;
grid-column-end: end;
grid-row-start: b;
grid-row-end: d;

grid-column-start and grid-row-start define the starting grid line of the element you are positioning using the name that you defined in your container. You set the end position of your element in the same way using grid-column-end and grid-row-end .

justify-self allows you to define how each item aligns within the grid along the row axis and align-self allows you to align each item along the column axis. They both take one of four values:

  • start Aligns items to the left or top of the grid area.
  • end Aligns items to the right or bottom of the grid area.
  • center centers items in the grid area.
  • stretch (the default) fills the whole width or height of the grid area.

Which Do I Choose?

Now that we have a general understanding of the capabilities of both tools, let’s talk about how to use them. The first thing to think about is how many directions you need to layout your elements. If you are only working in one dimension (think nav buttons in a header or a vertical menu on the side of your page), Flexbox is probably the correct choice because it will require less code and give you a lot of speed and flexibility. If, on the other hand, you are laying out an entire page with content that needs to be positioned both horizontally and vertically on the page then it’s time to use CSS Grid! In this instance taking the time to layout a grid will allow you to position elements on your page quickly and easily.

Combining the Two

Another really useful aspect of these layout tools is the fact that you can combine them very easily and effectivley.

Let’s say we have a basic web page with a header along the top, a main section with multiple elements and a navigation bar down one side. First, we ask ourselves how many directions we need to lay out our elements. Since we have multiple items positioned in two directions we know we need a grid.

But wait! The inside of our navigation bar doesn’t need a grid, it’s just got a few buttons that need to be placed in a vertical row. Not to worry! Since the container elements only affect the layouts of their direct children, we can use CSS grid to layout the main areas of our page including our navigation bar. With our nav bar successfully positioned, all we need to do is make it a Flexbox container and we can easily layout the buttons inside of it.