Introduction

<^>Flexbox<^> is a great way to get more flexibility in your layouts and to simplify responsive layout design. It makes it easy to align elements on a 2D plane and is pretty easy to use once you get familiar with the main properties.

The first step is to set <^>display: flex<^> on a container element. The children to the flex container become flex items. A set of properties can be applied to flex containers, and have an effect to all the items as a whole, and a different set of properties can be applied to flex items and have their effect on the targeted items. Flex items can in turn also be flex containers for the elements it contains, making it easy to create complex layouts.

[info] Browser Support: 2020 data shows 98% of browsers worldwide now support flexbox without the need for vendor prefixes.

Following is a quick primer to help make sense of Flexbox at a glance. This won't be an exhaustive list of all the available properties, values and edge cases, but rather a quick rundown of the most useful or commonly used properties.

Flex Container Properties

flexbox illustration for: Flex Container Properties

Here's a container with 3 <^>span<^> flex items, without Flexbox:

				
					
&lt;div class="box"&gt;

 &lt;span class="item"&gt;

 &lt;img src="/images/dino.svg" width="64" height="45" alt="Dino Sammy"&gt;

 &lt;/span&gt;

 &lt;span class="item"&gt;

 &lt;img src="/images/steampunk.svg" width="64" height="45" alt="Steampunk Sammy"&gt;

 &lt;/span&gt;

 &lt;span class="item"&gt;

 &lt;img src="/images/skeleton.svg" width="64" height="45" alt="Skeleton Sammy"&gt;

 &lt;/span&gt;

&lt;/div&gt;

				
			
				
					&lt;div class="demo_wrap no-flex"&gt;
				
			

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Punk Sammy">

</span>

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Pony Sammy">

</span>

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Dino Sammy">

</span>

</div>

display: flex

Now, let's improve it automagically simply by setting <^>display: flex<^> on the container. Notice how the items now automatically expand to the available space in the container:

				
					
.container {

 display: flex;

}

				
			
				
					&lt;div class="demo_wrap"&gt;
				
			

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Punk Sammy">

</span>

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Pony Sammy">

</span>

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Dino Sammy">

</span>

</div>

flex-direction

You can change the direction of the items using the <^>flex-direction<^> property:

				
					
.container {

 display: flex;

 flex-direction: column;

}

				
			
				
					&lt;div class="demo_wrap column"&gt;
				
			

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Punk Sammy">

</span>

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Pony Sammy">

</span>

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Dino Sammy">

</span>

</div>

The default is <^>row<^> and the additional available values are <^>row-reverse<^>, <^>column<^>, <^>column-reverse<^>.

row-reverse and column-reverse change the visual order of the items, without having to change the order of the HTML markup:

				
					
.container {

 display: flex;

 flex-direction: column-reverse;

}

				
			
				
					&lt;div class="demo_wrap column-reverse"&gt;
				
			

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Punk Sammy">

</span>

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Pony Sammy">

</span>

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Dino Sammy">

</span>

</div>

The ability to change between the row and column directions makes it very easy to adapt layouts on smaller devices with just one CSS rule change in a media query.

justify-content

Use <^>justify-content<^> to align the items on the main axis. The main axis is the Y axis when flex-direction is column and the X axis when flex-direction is row.

The default value is <^>flex-start<^> and the additional available values are <^>flex-end<^>, <^>center<^>, <^>space-between<^>, <^>space-around<^> and <^>space-evenly<^>.

				
					&lt;div class="demo_tabs justify-content"&gt;
				
			

justify-content:

<a name="flex-start">flex-start</a>

<a name="flex-end">flex-end</a>

<a name="center">center</a>

<a name="space-between">space-between</a>

<a name="space-around">space-around</a>

<a name="space-evenly">space-evenly</a>

<style>

.justify-content > [name="flex-start"]:hover ~ .demo_wrap { justify-content: flex-start; }

.justify-content > [name="flex-end"]:hover ~ .demo_wrap{ justify-content: flex-end; }

.justify-content > [name="center"]:hover ~ .demo_wrap { justify-content: center; }

.justify-content > [name="space-between"]:hover ~ .demo_wrap { justify-content: space-between; }

.justify-content > [name="space-around"]:hover ~ .demo_wrap { justify-content: space-around; }

.justify-content > [name="space-evenly"]:hover ~ .demo_wrap { justify-content: space-evenly; }

</style>

				
					&lt;div class="demo_wrap justify-content"&gt;
				
			

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Punk Sammy">

</span>

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Pony Sammy">

</span>

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Dino Sammy">

</span>

</div>

</div>

align-items

<^>align-items<^> is analogous to justify-content, but allows to align the items in the cross-axis. It defaults to <^>stretch<^> and also accepts <^>flex-start<^>, <^>flex-end<^>, <^>center<^> and <^>baseline<^>:

				
					&lt;div class="demo_tabs align-items"&gt;
				
			

align-items:

<a name="stretch">stretch</a>

<a name="flex-start">flex-start</a>

<a name="flex-end">flex-end</a>

<a name="center">center</a>

<a name="baseline">baseline</a>

<style>

.align-items > [name="stretch"]:hover ~ .demo_wrap { align-items: stretch; }

.align-items > [name="flex-start"]:hover ~ .demo_wrap { align-items: flex-start; }

.align-items > [name="flex-end"]:hover ~ .demo_wrap { align-items: flex-end; }

.align-items > [name="center"]:hover ~ .demo_wrap { align-items: center; }

.align-items > [name="baseline"]:hover ~ .demo_wrap { align-items: baseline; }

</style>

				
					&lt;div class="demo_wrap align-items"&gt;
				
			

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Punk Sammy">

</span>

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Pony Sammy">

</span>

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Dino Sammy">

</span>

</div>

</div>

align-content

<^>align-content<^> is similar to <^>align-items<^>, but it only has an effect when there's more than one line of flex items (see flex-wrap below). It defaults to <^>stretch<^> and also accepts <^>flex-start<^>, <^>flex-end<^>, <^>center<^>, <^>space-between<^>, <^>space-evenly<^>:

				
					&lt;div class="demo_tabs align-content"&gt;
				
			

align-content:

<a name="stretch">stretch</a>

<a name="flex-start">flex-start</a>

<a name="flex-end">flex-end</a>

<a name="center">center</a>

<a name="space-between">space-between</a>

<a name="space-around">space-around</a>

<a name="space-evenly">space-evenly</a>

<style>

.align-content > [name="stretch"]:hover ~ .demo_wrap { align-content: stretch; }

.align-content > [name="flex-start"]:hover ~ .demo_wrap { align-content: flex-start; }

.align-content > [name="flex-end"]:hover ~ .demo_wrap { align-content: flex-end; }

.align-content > [name="center"]:hover ~ .demo_wrap { align-content: center; }

.align-content > [name="space-between"]:hover ~ .demo_wrap { align-content: space-between; }

.align-content > [name="space-around"]:hover ~ .demo_wrap { align-content: space-around; }

.align-content > [name="space-evenly"]:hover ~ .demo_wrap { align-content: space-evenly; }

</style>

				
					&lt;div class="demo_wrap align-content items-wide2 wrap2"&gt;
				
			

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Punk Sammy">

</span>

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Pony Sammy">

</span>

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Dino Sammy">

</span>

</div>

</div>

flex-wrap

By default items won't wrap (default of <^>nowrap<^>), so if the items take more space than what's available they'll overflow. This can be fixed with <^>flex-wrap<^> set to a value of <^>wrap<^>:

				
					&lt;div class="demo_tabs flex-wrap"&gt;
				
			

flex-wrap:

<a name="nowrap">nowrap</a>

<a name="wrap">wrap</a>

<style>

.flex-wrap > [name="nowrap"]:hover ~ .demo_wrap { flex-wrap: nowrap; }

.flex-wrap > [name="wrap"]:hover ~ .demo_wrap { flex-wrap: wrap; }

</style>

				
					&lt;div class="demo_wrap flex-wrap items-wide wrap"&gt;
				
			

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Punk Sammy">

</span>

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Pony Sammy">

</span>

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Dino Sammy">

</span>

</div>

</div>

Flex Item Properties

align-self

<^>align-self<^> is just like <^>align-items<^>, but only for specific items. This makes it easy to have flex items that break out of the main rule:

				
					&lt;div class="demo_tabs align-self"&gt;
				
			

align-self:

<a name="stretch">stretch</a>

<a name="flex-start">flex-start</a>

<a name="flex-end">flex-end</a>

<a name="center">center</a>

<a name="baseline">baseline</a>

<style>

.align-self > [name="stretch"]:hover ~ .demo_wrap .item:first-child { align-self: stretch; }

.align-self > [name="flex-start"]:hover ~ .demo_wrap .item:first-child { align-self: flex-start; }

.align-self > [name="flex-end"]:hover ~ .demo_wrap .item:first-child { align-self: flex-end; }

.align-self > [name="center"]:hover ~ .demo_wrap .item:first-child { align-self: center; }

.align-self > [name="baseline"]:hover ~ .demo_wrap .item:first-child { align-self: baseline; }

</style>

				
					&lt;div class="demo_wrap align-self"&gt;
				
			

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Punk Sammy">

</span>

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Pony Sammy">

</span>

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Dino Sammy">

</span>

</div>

</div>

flex-grow

With <^>flex-grow<^> we can control the amount of space that a flex item takes compared to the other items. flex-grow accepts a numeric value and it represents a fraction of the available space, depending on the flex-grow value of the other items. It defaults to a value of 0, which means that the item won't take up available empty space.

Since it's based on proportion, setting all items to, for example, a flex-grow of 200 is the same as setting all items to a flex-grow of 1.

In the below example, the first item has a default flex-grow value of 0, the second item has a value of 1 and the third item has a value of 2:

				
					&lt;div class="demo_wrap" style="flex-direction: row; align-items: center; height: 200px;"&gt;
				
			

<span class="item">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Punk Sammy">

</span>

<span class="item" style="flex-grow:1;">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Pony Sammy">

flex-grow: 1

</span>

<span class="item" style="flex-grow:2;">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Dino Sammy">

flex-grow: 2

</span>

</div>

flex-shrink

<^>flex-shrink<^> is the opposite of flex-grow and defines the shrinkability of items. It defaults to a value of 1, meaning that the items can shrink and, just as with flex-grow, it's based on proportion with the other items.

flex-basis

<^>flex-basis<^> defines the starting space that an item takes, but it's not a guarantee because it also depends on space availability or if there's extra space to fill.

To illustrate, in the following example, all items have a flex-basis of <^>25%<^>:

				
					&lt;div class="demo_wrap" style="flex-direction: row; align-items: center; height: 200px;"&gt;
				
			

<span class="item" style="flex-basis: 25%;">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Punk Sammy">

</span>

<span class="item" style="flex-basis: 25%;">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Pony Sammy">

</span>

<span class="item" style="flex-basis: 25%;">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Dino Sammy">

</span>

</div>

…but now let's also give a flex-grow of 1 to the first flex item. In the following example, all items have a flex-basis of <^>25%<^>, but the first item takes up the rest of the available space because it has a flex-grow value of 1:

				
					&lt;div class="demo_wrap" style="flex-direction: row; align-items: center; height: 200px;"&gt;
				
			

<span class="item" style="flex-basis: 25%; flex-grow:1;">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Punk Sammy">flex-grow:1

</span>

<span class="item" style="flex-basis: 25%;">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Pony Sammy">

</span>

<span class="item" style="flex-basis: 25%;">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Dino Sammy">

</span>

</div>

…and finally, here our third item has a flex-basis of 77% and refuses to shrink to make space for the other items that have a flex-basis of 25% because it has a flex-shrink value of 0:

				
					&lt;div class="demo_wrap" style="flex-direction: row; align-items: center; height: 200px;"&gt;
				
			

<span class="item" style="flex-basis: 25%;">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Punk Sammy">

</span>

<span class="item" style="flex-basis: 25%;">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Pony Sammy">

</span>

<span class="item" style="flex-basis: 77%; flex-shrink:0;">

<img src="images/css-flexbox-section-1.png; width="64" height="45" alt="Dino Sammy">flex-basis: 77%; flex-shrink:0;

</span>

</div>

				
					
.item {

 flex-basis: 25%;

}

.item:last-child {

 flex-basis: 77%;

 flex-shrink: 0;

}

				
			

flex

<^>flex<^> is a shorthand property for the combination of <^>flex-grow<^>, <^>flex-shrink<^> and <^>flex-basis<^>. For example, here's the syntax for an item that has a flex-grow value of 2, flex-shrink value of 0 and flex-basis of 2rem:

				
					
.item {

 flex: 2 0 2rem;

}

				
			

<style>

.demo_tabs > a {

display: inline-block;

padding: 4px;

cursor: pointer;

}

.demo_tabs > a:hover {

background: rgba(114, 186, 94, 0.25);

}

.demo_wrap, .demo_tabs > a {

border: 2px dashed rgba(114, 186, 94, 0.35);

background: rgba(114, 186, 94, 0.05);

}

.demo_wrap {

display: flex;

height: 250px;

grid-template-columns: 1fr 1fr 1fr;

grid-template-rows: auto;

margin-bottom: 1.2rem;

}

.demo_wrap.no-flex {

display: block;

}

.demo_wrap.column {

flex-direction: column;

}

.demo_wrap.column-reverse {

flex-direction: column-reverse;

}

.demo_wrap .item {

background: rgba(255, 213, 70, 0.4);

border: 2px dashed rgba(236, 198, 48, 0.5);

padding: .875rem;

}

.demo_wrap .item img {

display: inline;

margin-left: 0;

margin-right: 0;

max-width: unset;

border: none;

}

.demo_wrap.items-wide {

align-items: center;

}

.demo_wrap.items-wide .item,

.demo_wrap.items-wide2 .item {

width: 45%;

}

.demo_wrap.wrap2 {

flex-wrap: wrap;

}

</style>