Flexbox Layouts

This chapter will explore the Flexbox layout model, one of the most powerful and flexible ways to design responsive web layouts with CSS. In later chapters, we will cover what "responsive" design is in more detail, but for now, the short answer is to ensure that your web page looks good on all device sizes (from your phone to your desktop).

Flexbox (short for Flexible Box) allows you to create complex layouts with simple and intuitive syntax. Unlike the float property, we set our parent container to display: flex; to use it. This changes the default behavior of our elements. Because this single property changes the behavior of the container and its children, we will use a lot of new terminology in this section. Don't worry about remembering everything; you can always dive back here when needed.

Note: If you need a reminder of how different display values impact your layout, here is the chapter in which we covered it.

Before we dive into examples, let's understand some basic Flexbox terminology:

  • Flex Container: The parent element that contains flex items. To create a flex container, you set the display property of the parent to flex or inline-flex.
  • Flex Items: The direct children of the flex container.
  • Main Axis: The primary axis along which flex items are laid out (default is horizontal).
  • Cross Axis: The axis perpendicular to the main axis.

Here's a diagram showing each of these to visualize these concepts better:

Diagram of a CSS flexbox layout showing a container with multiple items arranged along the main axis (horizontal) and the cross axis (vertical). The container is marked as a "flex container," with arrows indicating the main axis running from left to right and the cross axis running from top to bottom. The items inside the container are labeled 'flex items' and are aligned according to the specified axis directions.

Creating a Flex Container

To start using Flexbox, you need to define a flex container.

This is as simple as adding the following to your parent container:

.container {
  display: flex;
}

Here's an example with the children being given fixed heights and widths:

Now that we have a flex container, let's alter some properties to show you how it affects things:

Main Properties of a Flex Container

flex-direction

  • Defines the direction of the main axis.
  • Values: row (default), row-reverse, column, column-reverse.
.container {
    display: flex;
    flex-direction: row; /* Horizontal layout */
}

Here's our initial example with all of the different directions applied:

The one thing to notice is how the change of values from row to column changes the axis:

Diagram of a CSS flexbox layout showing a container with multiple items arranged along the main axis (vertical) and the cross axis (horizontal). The container is marked as 'flex container,' with arrows indicating the main axis running from left to right and the cross axis running from top to bottom. The items inside the container are labeled 'flex items' and are aligned according to the specified axis directions.

The arrow directions are reversed when we apply the row-reverse or column-reverse.

justify-content

  • Aligns flex items along the main axis.
  • Values: flex-start (default), flex-end, center, space-between, space-around, space-evenly.
.container {
    display: flex;
    justify-content: center; /* Center items horizontally */
}

Here's an example of all of them in action with a flex-direction: row; container:

Edit the CodePen and try it out with a flex flex-direction: column;.

align-items

  • Aligns flex items along the cross-axis.
  • Values: stretch (default), flex-start, flex-end, center, baseline.
.container {
   display: flex;
   align-items: center; /* Center items vertically */
}

To show how each works and their effects on the children, here's a CodePen. The only element with a fixed height in this list is "Box 2", and that's so you can see how the stretch or default setting "stretches" your child elements:

flex-wrap

  • By default you'll notice that elements don't wrap or go to a new line in a flex container. We can change this behavior by using flex-wrap.
  • Values: nowrap (default), wrap, wrap-reverse.
.container {
    display: flex;
    flex-wrap: wrap; /* Allow items to wrap onto multiple lines */
}

Here is a CodePen to play around with and see it in action:

Flex Items Properties

Flex items have properties that control their size and growth behavior. This can also override at an item level the default behaviors inherited by the parent flex container:

flex-grow

  • Defines the ability for a flex item to grow relative to the rest of the items.
  • Value: A number (default is 0).
.item {
    flex-grow: 1; /* Items will grow to fill available space */
}

Here's it in action with some different numbers:

You can see that you can define ratios in the numbers, and it'll fill the space. In the second example, if only one item has the flex-grow property, it can take the remaining space.

## flex-shrink

  • Defines the ability for a flex item to shrink if necessary. You can think of it as the element you don't mind if it gets squashed.
  • Value: A number (default is 1).
.item {
    flex-shrink: 1; /* Items will shrink if needed */
}

Here's a CodePen to play with:

flex-basis

  • Defines the default size of an element before the remaining space is distributed.
  • Value: A length value or auto (default is auto).
.item {
   flex-basis: 100px; /* Set initial size of items */
}

Open the CodePen and you can see what happens when you resize the window:

align-self

  • Overrides the align-items property for individual flex items.
  • Values: auto (default), flex-start, flex-end, center, baseline, stretch.
.item {
  align-self: center; /* Center this item on the cross axis */
}

Here's a CodePen to try out the different values:

Practical Flexbox Layout Example

Let's create a more complex layout using Flexbox, including a header, sidebar, main content, and a footer.

Here's the CodePen so you can explore the code.

  • The .container class is set to display: flex with flex-direction: column to arrange its children vertically.
  • .header and footer: These elements span the full width of the container and have padding and background colors for visual distinction.
  • The .main class is a flex container itself, arranged horizontally by default. It contains the sidebar and main content.
  • The .sidebar has a fixed width, while the .content grows to fill the remaining space using flex-grow: 1.

I hope you can see that you can do pretty much anything you want in a page layout with Flex. There was some content here, so don't forget to practice these skills. In the next section will cover how to use CSS grids for layouts.

As a cheatsheet, one of my most visited guides on is this A Complete Guide to Flexbox. Worth bookmarking for when you are trying to figure things out.

BeginnerCSS
Avatar for Niall Maher

Written by Niall Maher

Founder of Codú - The web developer community! I've worked in nearly every corner of technology businesses: Lead Developer, Software Architect, Product Manager, CTO, and now happily a Founder.

Loading

Fetching comments

Hey! 👋

Got something to say?

or to leave a comment.