The ultimate guide to CSS Flexbox

Master CSS Flexbox with this comprehensive guide. Learn to create responsive, flexible, and customizable web layouts with ease.

If you've ever found yourself banging your head against the wall in frustration while trying to understand Flexbox, you're not alone. As a developer, I've wrestled with this CSS layout method for longer than I care to remember, so I know how daunting it can feel. But fear not, I'm here to help!

Watch the lesson

Getting started with Flexbox

Flexbox is a powerful tool in your CSS toolbox, designed to make responsive layouts a breeze. It's divided into two main components: the flex container and its contents, called flex items.

To start using Flexbox, you set an element's CSS display property to flex. If you've ever dabbled with this, you'll have noticed that the child elements (our flex items) now align from left to right in a neat, single row. The magic behind this transformation? A CSS property called flex-direction, which, by default, is set to row.

Imagine this row as an invisible line, known as the main axis, that your flex items are neatly arranged along. This concept of the main axis will become crucial as you delve deeper into the world of Flexbox.

The true beauty of flex-direction lies in its versatility. It's not just confined to a simple row layout. In fact, it offers three additional values: row-reverse, column, and column-reverse. The value row-reverse mirrors the default row, aligning the flex items from right to left. Meanwhile, column alters the orientation of the main axis, positioning the flex items from top to bottom. As the name suggests, column-reverse, flips this on its head, aligning the items from bottom to top.

Flexbox row flex-direction and main-axis
Flexbox row-reverse flex-direction and main-axis
Flexbox column flex-direction and main-axis
Flexbox column-reverse flex-direction and main-axis

Mastering main-axis alignment in Flexbox

Now that we've dipped our toes into the world of Flexbox, let's dive a little deeper. A key aspect of mastering this layout method is understanding how to manipulate the alignment of items on the main axis. This is particularly useful when it comes to distributing any extra space within the parent container. The secret? A CSS property named justify-content.

By default, justify-content is set to flex-start. This positions the flex items towards the start of the flex-direction. It's easy to fall into the trap of thinking flex-start equates to aligning items to the left. However, remember, it's all relative to the main axis!

Take, for instance, when we experimented with row-reverse as the value for flex-direction. Did you notice the items shifting to the right? That's because flex-start adapted to the new main axis, beginning from the right and moving to the left.

With the concept of alignment along the main axis now firmly entrenched in your mind, let's explore some other popular values for justify-content.

  • flex-end: This value aligns items towards the end of the flex-direction, essentially the polar opposite of flex-start.

  • center: Quite self-explanatory, this value centrally aligns the flex items along the main axis.

  • space-between: This evenly distributes the flex items along the main axis. However, the first and last items align at the line's start and end.

  • space-around: This also distributes the items evenly but with equal space surrounding each individual item.

  • space-evenly: The ultimate equalizer, this property ensures the same amount of space surrounds each item, including the space around the outermost edges of the first and last items.

justify-content: flex-start
justify-content: flex-end
justify-content: center
justify-content: space-between
justify-content: space-around
justify-content: space-evenly

Controlling cross-axis alignment in Flexbox

So far, our journey through Flexbox has revolved around the main axis. However, we have yet to discuss another equally important player on the stage: the cross-axis. Running perpendicular to the main axis, the cross-axis provides an additional dimension for manipulating the position of our flex items.

In the case of row flex-directions, the cross-axis runs vertically. Conversely, for column flex-directions, the cross-axis spans horizontally. Now, why should you care about this axis? Because it opens up a new world of alignment possibilities, achievable through the align-items CSS property.

The align-items property has five frequently used values: flex-start, flex-end, center, stretch, and baseline.

  • stretch: This is the default setting for align-items. It expands the flex items to fill the parent container while still respecting max-height for row flex-direction and min-width for column flex-direction.

  • flex-start: This aligns the items to the start of the cross-axis.

  • flex-end: This does the opposite, aligning the items to the end of the cross-axis.

  • center: As you might guess, this value centers all the items along the cross-axis.

  • baseline: This is a unique alignment option. If the flex items contain text, baseline aligns the text along an imaginary common line upon which the text of each item sits.

align-items: stretch
align-items: flex-start
align-items: flex-end
align-items: center
align-items: baseline

Understanding the cross-axis in Flexbox gives us more control over our layouts. We can create more customized layouts by aligning items along the main and cross axes.

Managing flex item wrapping

Before we dive into the final alignment property for flex containers, let's take a detour and explore the world of flex-wrap.

The flex-wrap property controls how flex items behave when they can't all fit within a single line in their container. By default, flex-wrap is set to nowrap, which means the items will automatically adjust their sizes to try and squeeze onto one line. This can be convenient in some scenarios, but it might sometimes not give the visual result you want.

That's where the power of flex-wrap really shines. By setting flex-wrap to wrap, the flex items break free from their single-line confinement and wrap onto multiple lines, moving from top to bottom. If you want to reverse the wrapping of items onto multiple lines, you can use wrap-reverse to make the items wrap from bottom to top.

flex-wrap: nowrap
flex-wrap: wrap
flex-wrap: wrap-reverse

With the flex-wrap property, you have more control over the layout and appearance of your flex items. It allows you to decide whether you want your items on a single line or spread out across multiple lines. So, feel free to experiment with flex-wrap and see how it can enhance your layouts.

Optimizing alignment in multi-line flex containers

Having now explored flex-wrap, we're ready to tackle the final alignment property for flex containers: align-content. This property comes into play when you have flex items that span multiple rows, making it an essential tool for managing multi-line flex containers.

A flex container's align-content value is set to normal by default, which packs the items in their default position. If you wish to take control and override this setting, you have several popular options at your disposal:

  • flex-start

  • flex-end

  • center

  • stretch

  • space-between

  • space-around

  • space-evenly

align-content: normal
align-content: flex-start
align-content: flex-end
align-content: center
align-content: stretch
align-content: space-between
align-content: space-around
align-content: space-evenly

If these values look familiar, it's because they behave much like their counterparts in justify-content and align-items. The difference here is that these values specifically apply to the wrapped elements in a multi-line flex container.

Taking control of element spacing

When you thought we'd covered all the bases, there's one more Flexbox property to introduce: row-gap and column-gap. These properties allow you to control the space between flex items along the rows and columns, respectively, adding an extra level of finesse to your layouts.

Setting row-gap will inject space between elements along the rows, while column-gap spaces out elements along the columns. There's also a shorthand method called gap. If you set two values for gap, the first will apply to the row gap and the second to the column gap. But, if you set only one value, it applies equally to the row and column gap.

Flexbox column-gap
Flexbox row-gap
Two values set on gap property
One value set on gap property

These properties act as a kind of minimum “gutter” between your elements. They ensure that the flex items maintain a certain distance from each other based on the value you set. This is especially useful when you need to guarantee consistent spacing between elements in your layout, regardless of the screen size or the number of items.

Column gap with space-between example
Column gap acts as a minimum space between flex items

Adjusting the responsiveness of flex items

With all the CSS properties for the flex container covered, let's focus on the properties that can be applied to the flex items themselves. These properties offer control over the individual items within your flex container, giving you even more flexibility in layouts.

First up is flex-grow. This property determines a flex item's ability to grow within its parent container if necessary. By default, a flex item has a flex-grow property of 0. This means it will only occupy as much space as its content requires unless you explicitly set a width or height on the item.

The value you assign to flex-grow is unitless and is a proportion for Flexbox to calculate the amount of space to allot to the flex item. For instance, if each flex item has a flex-grow of 1, they'll all occupy equal space within the container. However, if one flex item has a flex-grow of 2, it will take up twice the space of the other items with a flex-grow of 1.

Next up is flex-shrink. This property functions much like flex-grow, but instead of controlling an item's ability to grow, it dictates its ability to shrink within its parent container if necessary.

Both flex-grow and flex-shrink can initially be challenging to understand. I personally found them to be the most difficult Flexbox concepts to grasp. A common stumbling block is to view these properties as units of measurement rather than the proportions they represent. Remember, flex-grow and flex-shrink are about relative proportions, not absolute measurements.

Flex items with flex-grow set to one are the same size
A flex-item with flex-grow of two is twice as big as items with flex-grow of one
flex-shrink controls the rate at which a flex-item will shrink inside the parent container

With these properties under your belt, you can exercise fine-tuned control over your flex items, ensuring your layouts are flexible and precisely managed.

Setting the default size of flex items

Next on our journey through Flexbox properties is flex-basis. This property sets a flex item's default size before distributing the container’s remaining space. The default value for flex-basis is auto, which tells Flexbox to look at the item's width, height, and flex-grow values to figure out how to distribute the extra space.

You can also set flex-basis to a specific length, such as pixels, rems, or percentages. If you set it to 0, the extra space around the content is not considered in the calculations. For instance, when flex-basis is set to 0 and flex-grow is set to 1, all the items will be the same size.

Flex items with a flex-basis of zero have equal sizes

However, when flex-basis is set to auto, the size of the items may vary, but the spacing around the content will remain consistent.

Flex-items with a flex-basis of auto have equal spacing around the content

Mixing flex-basis with width is easy, but there's a crucial difference. While width is a fixed value, flex-basis calculates its size based on the available space, factoring in properties like row-gap and column-gap.

If you want to streamline your CSS, Flexbox offers a handy shorthand property: flex. This property allows you to set flex-grow, flex-shrink, and flex-basis all in one go. This makes managing your flex items and keeping your CSS neat and tidy even easier.

To sum up, flex-basis and the flex shorthand property give you more control over your flex items. They enable you to manage the size of your items in relation to the available space in your flex container, providing another layer of flexibility in your layouts.

Gaining more control over flex items

A few more flex item properties are worth understanding, even if you might not use them as frequently as others. These properties, order and align-self, provide additional controls over your flex items, giving you even more power to create flexible and dynamic layouts.

Let's start with order. By default, flex items are laid out according to their order in the source code. However, the order property lets you override this default behavior. You can rearrange your flex items without touching your HTML by simply assigning different order values to your items. The order property even supports negative numbers, giving you a high level of control over your layout.

Change the order of a flex item with the order property

Next up is align-self. This property allows a flex item to break away from the alignment set by the align-items property on the flex container. The align-self takes the same values as align-items and applies them directly to a single flex item. This means that you can individually adjust the alignment of each flex item, regardless of the overall alignment set on the container.

Allow a flex item to break out of the align-items property set on the parent container

In summary, while order and align-self might not be your go-to properties when working with Flexbox, they're incredibly useful tools to have in your CSS toolbox. These properties offer even more control over your flex items, allowing for highly customizable and adaptable layouts.


In this guide, we've delved into the world of CSS Flexbox, a robust tool for creating responsive layouts. We first introduced the basics of Flexbox, its two primary components: the flex container and flex items. We've covered how the display property sets the stage for Flexbox and the role of flex-direction in shaping the layout. We've also discussed the importance of the main and cross axes, how to use justify-content and align-items for alignment, and flex-wrap for managing space when items overflow a single line.

Continuing our journey, we explored align-content for multi-line flex containers and the gap properties (row-gap, column-gap, gap) for managing spaces between flex items. We then examined flex items properties: flex-grow and flex-shrink for controlling the proportions of items, and flex-basis for setting the default size before space distribution. The flex shorthand was introduced for more efficient code writing.

Finally, we rounded off with order and align-self, two less frequently used but powerful properties offering control over item arrangement and individual alignment. This comprehensive guide to CSS Flexbox provides developers with an extensive toolbox to create more flexible, responsive, and custom layouts.