Skip to content

CSS Flexbox Tutorial for Beginners (With Interactive Examples)

There’s certainly no shortage of CSS flexbox tutorials and similar content online promoting and teaching flexbox to beginners. The now-ubiquitous layout technique can be learned from a number of different resources. But I hope this CSS flexbox tutorial for beginners will be a little different.

In this CSS flexbox tutorial I’m aiming to teach you all of the features of the Flexbox Layout Module using fully interactive demonstrations that really drive home how flexbox features affect elements on an HTML page.

CSS Flexbox Tutorial for Beginners: How to Use Flexbox

About the interactive demos

As mentioned, all the demos in this CSS flexbox tutorial will be fully interactive. Each one will illustrate a specific flexbox feature and you’ll be able to click one or more buttons in just about every demo to see the effects of those features.

In addition, most demos will include a “toggle direction” button that will toggle the direction property on the container element between ltr and rtl. This will allow you to see how the particular feature works in both types of environments – using left-to-right languages like English and Spanish or right-to-left languages like Arabic or Hebrew.

In case you haven’t used this property before, here’s a demo with some example text that uses a right-to-left language:

There are a few ways to accomplish language definition in HTML or CSS, but in the above example I’m using direction: rtl in the CSS for that paragraph element. In the flexbox demos, I won’t be using any language – just elements with dummy content – but the direction will be able to toggle via JavaScript.

Creating the flexbox container

The first feature it’s important to know when working with flexbox is how to define the flex container. Before you begin aligning, centering, and justifying elements inside a container, you first have to specify that the parent container is a flex container:

.flex-container {
  display: flex;
Code language: CSS (css)

Once you have this in place, all the child elements inside .container become flex items, because they now exist inside a flex formatting context. Below is an interactive CodePen demo that will allow you to see what happens when you toggle a container between display: flex and display: block.

In this example, the only flexbox-related CSS that’s applied is display: flex. The space you see between the flex items is a small margin I’ve added for clarity. Later, I’ll discuss different ways to space flex items using flexbox features.

What do you see happening when you toggle the flex container on and off? First, it’s important to note that all the elements, including the container and its children, are <div> elements. This means they’re all block-level elements by default. In this CSS flexbox tutorial, I’m mainly going to deal with the behavior of flexbox properties on block-level elements, because that’s the most common use case.

By default, block elements are placed below previous content, so the items are stacked vertically. When display: flex is toggled on, however, the elements align horizontally while still maintaining their dimensions and the specified margins.

Understanding the flex container

As the initial demo shows, a flex container will by default display its flex children horizontally. This is what’s referred to as the main axis of a flex container. Later, I’ll show you how to display the elements vertically in a flex container. In that case, the items will be laid out on what’s referred to as the cross axis.

The following diagram shows these two axes:

Illustrating the two axes of a flex container

As shown, the cross axis flows perpendicular to the main axis. And it’s important to note that although non-flex blocks are laid out visually in the same direction as the cross axis, technically that doesn’t qualify as a flexbox cross axis until the container is set to display: flex.

Flexbox properties for the container

In this CSS flexbox tutorial, first, I’m going to discuss the different properties you can apply to the flex container. Later, I’ll show you how to target the flex items.

By dividing this CSS flexbox tutorial in this way, you’ll be able to easily reference the different features depending on if you want to do something more universal to all the items as a group via the flex container or if you want to target the flex items themselves.

Determining the direction of the flex container: flex-direction

As discussed, a flex container can have elements flowing either vertically (on the cross axis) or horizontally (along the main axis). To specify the direction you can use the flex-direction property, which takes one of four values, the default being row.

.flex-container {
  display: flex;
  flex-direction: row;
Code language: CSS (css)

Here’s a breakdown of each value for flex-direction:

  • row – Elements are aligned horizontally along the main axis in the document’s current writing mode.
  • row-reverse – This value is likewise on the main axis but in reverse of the current writing mode.
  • column – As the name implies, this flows the flex items along the cross axis (vertically), taking into consideration the current writing mode
  • column-reverse – Same as column but reversed

You can see all the values in the following interactive demo:

Note that the boxes are numbered so you can easily see the effect of the *-reverse values.

Also note that in English and many other languages, the writing mode is set as left-to-right, whereas other languages it’s reversed. This is why you’ll often see more generic terminology used in newer CSS specifications, and why a specification like Logical Properties and Values was created. Logical properties make no assumption about the page’s language (unlike something like text-align: left, which does make assumptions), thus terms like ‘left’ and ‘right’ are not used but instead are replaced by ‘start’ and ‘end’.

Wrapping items: flex-wrap

The flex-wrap property allows you to determine how and if you want the flex items inside the container to wrap to the next line.

.flex-container {
  display: flex;
  flex-wrap: nowrap;
Code language: CSS (css)

The values break down as:

  • nowrap – Don’t wrap the items to the next line
  • wrap – Wrap the items if they don’t fit on a single line
  • wrap-reverse – Wrap the items if necessary but reverse their order in relation to the default writing direction

By default, items will not wrap – even if you specify widths that force the items to expand past the available space. Below is an interactive demo that demonstrates the three different values. Note that the width is set at 15% for all the flex items.

As you can see, even with a set width, the items fit on a single line when the flex container is set to flex-wrap: nowrap. Once the elements wrap, then they break onto multiple lines while respecting the specified widths.

Aligning elements along either axis: justify-content

The aptly-named justify-content property accepts one of five possible values and the syntax looks like this:

.flex-container {
  display: flex;
  justify-content: flex-start;
Code language: CSS (css)

A value of flex-start is the initial value. It’s easy to see the effect of each value using the demo below, but here’s a quick summary of each one:

  • flex-start – Pack the flex items to the start of the line
  • flex-end – Pack the flex items to the end of the line
  • center – Pack the flex items in the center
  • space-between – Flex items are evenly distributed with no space at the start or end outside of margins or padding
  • space-around – Flex items are evenly distributed with a “half size” of space at the start and end of each line

And here’s the interactive demo to help you visualize how each one works:

The values will behave in a fairly predictable way when you have two or more items, but notice the behavior with a single flex item:

As you can see, the space-between value behaves the same as flex-start on the lone element. A value of space-around behaves the same as center in this instance, but that’s fairly predictable.

The same property can also be used to align items in a cross-axis flex container, as shown in the following demo:

Aligning elements in the cross axis of the current line: align-items

The align-items property is a little tricky to get your head around because its name doesn’t really suggest what it does. This property helps you align each individual flex item perpendicular to the main axis, while the items still remain aligned along the main axis.

That might be a bit confusing. To make it more clear, let’s say I have five flex items in a flex container along the main axis (i.e. flex-direction: row). While these items remain in the row direction, I can align them individually in the perpendicular direction. If that’s still confusing, some code and an interactive demo will help greatly here.

.flex-container {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
Code language: CSS (css)

In order to see the effect of align-items, I’m setting the container’s flex-wrap property to wrap, and the demo will include enough items to allow you to see the effect more clearly. Here are the possible values:

  • stretch – The default; flex items are individually stretched to fit along the cross axis
  • flex-start – Aligns each element to the ‘start’ edge of the line along the cross axis
  • flex-end – Aligns each element to the ‘end’ edge of the line along the cross axis
  • center – Centers each flex item on the line along the cross axis
  • baseline – Centers each flex item with its text baseline

And here’s the demo:

Note that not only am I including ten flex items but some of them have different heights and line-heights to demonstrate how the different values behave.

As you can see, the items are aligned perpendicular in relation to the current flex line (which is the default row, or horizontal). Notice that the value stretch doesn’t stretch the flex items across the entire height of the container, but only across the item’s flex line, or ‘row’.

If I remove the extra line of flex items, note the behavior in the following demo:

Again the varying heights and line-heights help drive home the concept. This is one you’ll have to play around with to grasp its usefulness.

Handling extra space between flex lines: align-content

The align-content property is another one that’s a little tough to grasp at first. But it’s relatively easy to understand when you think about it the same way as justify-content except instead of dealing with the items and the space between them along the main axis, this property deals with the space between flex lines.

.flex-container {
  display: flex;
  flex-wrap: wrap;
  align-content: stretch;
Code language: CSS (css)

The values are the same as justify-content with the addition of stretch, the default:

  • stretch – Flex lines are stretched to take up the available space, making all flex lines the same height
  • flex-start – Lines are packed to the start (usually the top) of the container
  • flex-end – Lines are packed to the end (usually the bottom) of the container
  • center – Lines are packed to toward the center with equal space at top and bottom
  • space-between – Lines are evenly distributed with equal space between lines and no space at the top or bottom
  • space-around – Lines are evenly distributed with equal space but with half the leftover space at the top and bottom

The spec points out the following:

Only multi-line flex containers ever have free space in the cross-axis for lines to be aligned in, because in a single-line flex container the sole line automatically stretches to fill the space.

With that in mind, the interactive demo includes multiple flex lines:

Again I’ve included items with different sizes to demonstrate the behavior in an unusual context.

Flexbox properties for the flex items

So far, this interactive CSS flexbox tutorial has covered all the properties you can apply to the container. Once those are in place, there are a number of properties you can apply to one or more flex items (i.e. child elements of the flex container).

Let’s continue the CSS flexbox tutorial by considering the flex item properties.

Specifying the order of flex items: order

By default, flex items are laid out according to the order they appear in the HTML source. The order property can be applied to any flex item to adjust that item’s place in the source order.

.flex-item {
  order: 3;
Code language: CSS (css)

The order property accepts an integer that represents the order that the flex item appears relative to the its sibling flex items, taking into account any other order values that are present.

Here’s a simple demo that has three flex items. The options at the top allow you to change their order.

In that example, the three flex items change order similar to how you might adjust a three-column layout contrary to source order (which you might do for SEO purposes).

Understanding precedence when using order

To understand the order property a little better, note the following interactive demo. It’s probably confusing at first, especially if you don’t understand how order is determined in certain circumstances.

To understand what you’re seeing, here’s a breakdown:

  • Each of the numbered flex items has an order value set equal to its visible number
  • The one flex item that’s a different color changes its order when you select one of the number options

With that in mind, notice the somewhat strange behavior:

  • Although you’re giving the #5 flex item an order value of 1, it appears as the second item (the same happens when choosing 2, 3, or 4).
  • Choosing 5 brings it back to its starting place but choosing 6 leaves it at the 5 position
  • Choosing 7 puts it in the 6th position and choosing 8 puts it in the 7th position

Those behaviors are explained as follows:

  • The items all start with an existing order value. If two flex items share the same order, the one first in HTML source order will take precedence in flex order
  • Thus, items #1 through #4 all have precedence in order when they share the same order as the #5 item after it’s changed
  • Likewise, since #5 appears before the #6 through #12 items in the original source, #5 takes precedence when any of those share the same order value

Again, the main concept to keep in mind is that elements sharing the same order behave as if they have no order set in relation to one another.

Determining relative size of flex items: flex-grow

The flex-grow property accepts a number value (that may be fractional) that tells the browser how much a flex item will grow relative to the rest of the flex items in the flex container. It specifies how much of the remaining space is assigned to the item’s size.

.flex-item {
  flex-basis: auto;
  flex-grow: 0;
  flex-shrink: 1;      
Code language: CSS (css)

If the flex-direction is set to row, then the grow factor is applied to the flex item’s width. If it’s set to column, then the grow factor is applied to the flex item’s height.

In the code above, I’m also including flex-basis and flex-shrink (discussed later). These properties are designed to work together, so it’s encouraged to include all three, or use the shorthand (see later on flexbox shorthand properties).

Here’s a demo that allows you to increment the flex-grow property on a single flex item, so you can see the behavior:

Notice the flex container has three flex items. All three have their flex-grow property set to 0 (the default). The number input on the page allows you to increase the flex-grow value for the middle flex item, setting it to a decimal value between 0 and 1.

In this example, any number higher than 1 is the same as 1. The other flex items do not have a flex-grow value, so their flex-grow is at the default value of 0. Therefore, any value higher than 0 for the second flex item will result in that item taking up that percentage of the remaining space.

If however, the other items had their flex-grow values set at 1, then any item you wanted to be bigger would have to have a value higher than 1 to see any difference in size. To illustrate, here’s another demo, this time the #1 and #3 items start with flex-grow: 1 and the middle item starts with flex-grow: 0:

As you can see, the flex-grow value for any one flex item is relative to the flex-grow value for the others and the remaining space is assigned based on the difference in flex-grow values.

Determining relative size of flex items: flex-shrink

The flex-shrink property is probably the flexbox property that you’ll use the least of any of the ones in this CSS flexbox tutorial. It works somewhat in the reverse way that flex-grow works. In the example, I’ll start with the following code for all three flex items:

.flex-item {
  flex-basis: 500px;
  flex-grow: 1;
  flex-shrink: 0; 
Code language: CSS (css)

In the interactive demo, I’m setting the flex-shrink value to 1 for all the flex items, then I’m changing the middle item to flex-shrink: 0, which you can then adjust using the number input in increments of 0.05:

Likely you would use whole numbers for the shrink factor in a real-world example, but this just demonstrates that fractional values are possible. As you can see, as the flex-shrink value increases in relation to the flex-shrink of the other items, the targeted item’s size gets smaller, which is more or less opposite to how flex-grow works.

To clarify how this works:

  • All items are set with a flex-basis of 500px
  • Two of the items have a flex-shrink value of 1, which makes them shrink
  • The middle item starts with a flex-shrink value of 0, which means it’s not shrunk to begin with
  • When you incrementally increase the shrink value of the middle item, it shrinks accordingly
  • The other items get bigger as the middle item shrinks because both the shrink and grow factors are always calculated based on space available as well as relative to the other items’ shrink or grow factors

As already mentioned, these three properties are designed to work together, so you should get in the habit of including all three, or else using the shorthand.

Set the initial size of a flex item: flex-basis

The flex-basis property lets you define the size of a specific flex item before free space is distributed according to common flexbox calculations such as those already discussed.

The syntax is similar to width and height in CSS:

.flex-item {
  flex-basis: auto;
  flex-grow: 0;
  flex-shrink: 1;      
Code language: CSS (css)

The flex-basis property can accept one of the following values:

  • auto – The initial value, similar to how width and height values can be set to auto
  • content – This keyword is similar to auto but it calculates the size of the item based on the content it contains
  • length – Any length value (px, em, etc.)
  • percentage – Any percentage value

As of this writing, the content value is a new feature that’s supported only in Firefox, so the demo below doesn’t include content as an option.

Try changing the value of the number input. Notice how the size of the first flex item changes as its flex-basis gets larger. This allows you to adjust the size of a specific element before the rest of the available space is assigned.

And note that when using any of the three properties flex-basis, flex-grow, and flex-shrink, the effects they have will depend on whether the flex container is in row or column mode. Note the next CodePen that demonstrates this with the container now set to flex-direction: column:

As you can see, the value for flex-basis isn’t just tied to width but will affect the flex items depending on the flex-direction of the container.

Self-aligning a flex item: align-self

Earlier, I showed you how to use the align-items property on the flex container to determine alignment of the flex items across the cross axis while the items remain aligned on the main axis.

The align-self property allows you to define the same type of alignment but narrowed to a specific flex item. Recall that align-items is for the flex container; align-self is applied to one or more flex items.

.flex-item {
  align-self: flex-start;
Code language: CSS (css)

The align-self property accepts the same values as the align-items property with the only difference being that align-self also accepts the keyword auto. The auto value simply means that the flex item will determine any alignment based on the value of align-items on the container.

I’m going to use the same demo that I used earlier for align-items, except this time the values selected will be applied only to a single element of the ten (the #5 item).

To see the same values applied to a different element, move the .extra class in the HTML to a different element (the change will apply to the first element with a class of .extra, so there should only be one).

Flexbox shorthand properties

I’ve covered all the longhand flexbox properties so far, but you should be aware that some of the properties can be expressed using shorthand. I won’t provide any further demos in this section, just a breakdown of the shorthands.

The flex shorthand

The flex shorthand is applied to one or more flex items and represents three properties:

.flex-item {
  flex: <flex-grow> <flex-shrink> <flex-basis>;
Code language: CSS (css)

You can also supply a keyword value of none by itself to reset any existing flex values on the item. One of flex-grow or flex-basis must be present and flex-shrink is optional and must follow flex-grow.

Taking what I covered earlier for those individual longhand properties, an example might look like this:

.flex-item {
  flex: 0 1 300px;      
Code language: CSS (css)

This single declaration sets the flex-grow property to 0, the flex-shrink property to 1, and the flex-basis property to 300px.

I should also point out that the spec encourages use of the flex shorthand vs. the individual longhand properties. It says:

Authors are encouraged to control flexibility using the flex shorthand rather than with its longhand properties directly, as the shorthand correctly resets any unspecified components to accommodate common uses.

The flex-flow shorthand

The other shorthand property you have the option to use is flex-flow and it applies to the flex container. This property represents:

.flex-container {
   flex-flow: <flex-direction> <flex-wrap>;
Code language: CSS (css)

You’re only required to include one of the values. Because the possible values for each don’t overlap, you can include either property’s value by itself. The following example sets flex-direction to column and flex-wrap to wrap-reverse:

.flex-container {
   flex-flow: column wrap-reverse;
Code language: CSS (css)

Some real-world CSS flexbox snippets

Flexbox makes it easy to do a sticky footer with CSS, a common pattern where the footer stays at the bottom of the viewport until content pushes it down.

Use the buttons to add or remove paragraph content. This was previously only possible with various hacks and workarounds.

Flexbox also makes it easy to center any element vertically inside any container, regardless of the size of the element or its container – something that was virtually impossible in the past.

In the above demo, try resizing either the container or the flex item inside it. Whatever the size, the item will remain both horizontally and vertically centered. This is accomplished using just three lines of flexbox CSS on the container:

.flex-container {
  display: flex;
  align-items: center;
  justify-content: center;
Code language: CSS (css)

Finally, here’s a responsive CSS cards layout where each card is a media object. No floats, no display: inline-block or other grid-mimicking workarounds.

Card Layout + Media Objects with Flexbox

If you visit that CodePen, you can interactively add or remove card components to see how the layout behaves. With CSS flexbox, this is easy and there are no layout side effects to worry about like we used to have when using floats or other methods.

Wrapping up this CSS flexbox tutorial

I hope this interactive CSS flexbox tutorial has given you lots to experiment with if flexbox is a new concept to you. You can use CSS templates as a playground if you like. If you were already familiar with flexbox, maybe some of the details of the different features are clearer now.

Finally, if you’d like to fiddle around with the examples from this CSS flexbox tutorial, you can view all the interactive CodePen demos in this CodePen collection.

Have any questions about flexbox? Ask away in the comments section!

Don’t forget to join our crash course on speeding up your WordPress site. Learn more below:


Layout and presentation by Karol K and Chris Fitzgerald.

Yay! 🎉 You made it to the end of the article!
Louis Lazaris

Inline Feedbacks
View all comments

Or start the conversation in our Facebook group for WordPress professionals. Find answers, share tips, and get help from other WordPress experts. Join now (it’s free)!

Would love your thoughts, please comment.x