
Flexbox is a CSS layout module that lets you build flexible, adaptive layouts for your HTML elements. It is especially useful when a layout has to cope with different screen sizes and different devices.
With Flexbox you can align items horizontally or vertically, control the space between them and set the order in which they appear. It also gives you flexible ways to size items, which is exactly what a responsive layout needs.
To use Flexbox in your project, first declare a flex container with the CSS property display: flex or display: inline-flex on an HTML element. From there, the Flexbox properties control the layout of its children.
.container-flex {
display: flex;
}How to align items with Flexbox
One of the most useful things Flexbox does is align items flexibly. Several properties give you control over how items line up inside a flex container.
Horizontal alignment with justify-content
The justify-content property controls how items are aligned horizontally.
justify-content: flex-start;
justify-content: center;
justify-content: flex-end;
justify-content: space-between;
justify-content: space-around;
justify-content: space-evenly;
/*aligns the items on the left edge*/
.container {
justify-content: flex-start;
}
/*centres the items*/
.container {
justify-content: center;
}
/*aligns the items on the right edge*/
.container {
justify-content: flex-end;
}
/*spreads the items evenly between the left and right edges with no space at the edges*/
.container {
justify-content: space-between;
}
/*spreads the items evenly between the left and right edges with the same amount of space at both edges*/
.container {
justify-content: space-around;
}
/* spreads the items evenly between the left and right edges with the same amount of space at both edges and between each item */
.container {
justify-content: space-evenly;
}Vertical alignment with align-items
The align-items property controls how items are aligned vertically.
align-items: flex-start;
align-items: center;
align-items: flex-end;
align-items: stretch;
/* Align every item at the top */
.container {
align-items: flex-start;
}
/* Align every item in the middle */
.container {
align-items: center;
}
/* Align every item at the bottom */
.container {
align-items: flex-end;
}
/*makes the items match the height of their content*/
.container {
align-items: stretch;
}How to control the space between items with Flexbox
Flexbox also lets you control the space between items. Several properties handle spacing inside a flex container.
Adding space between items with margin
The margin property sets the space between an element and the elements around it. Use it when you want to space items one by one.
/* Add 20px of space between each item */
.item {
margin: 0 20px;
}Adding space around an item with padding
The padding property sets the space between the edges of an element and its content. Use it to add space around a single item.
/* Add 20px of space around an item */
.item {
padding: 20px;
}Using gap to space items out
Since CSS Grid Layout, Flexbox can use gap to add space between items. The property sets a uniform gap between every item in a flex container.
/* Add 20px of space between all the items */
.container {
gap: 20px;
}It works together with row-gap and column-gap when you need different spacing on rows and on columns. Two things to keep in mind: it only applies to the direct children of the flex container, and you should check browser support before relying on it.
The Flexbox properties
Flexbox comes with a long list of properties for building flexible, adaptive layouts. This section goes through the ones you will actually use.
flex-direction
The flex-direction property sets the direction items are laid out in a flex container. There are four possible values: row, row-reverse, column and column-reverse. The default is row.
flex-direction: row;
flex-direction: row-reverse;
flex-direction: column;
flex-direction: column-reverse;
/* Lays the items out in a row (default) */
.container {
flex-direction: row;
}
/* Lays the items out in a reversed row */
.container {
flex-direction: row-reverse;
}
/* Lays the items out in a column */
.container {
flex-direction: column;
}
/* Lays the items out in a reversed column */
.container {
flex-direction: column-reverse;
}
flex-wrap
The flex-wrap property defines whether the items of a flex container are laid out on a single line or on several lines. There are three possible values: nowrap (default), wrap and wrap-reverse, which stacks the lines in reverse order.
flex-wrap: nowrap;
flex-wrap: wrap;
/* Lays the items out on a single line (default) */
.container {
flex-wrap: nowrap;
}
/* Lays the items out over several lines */
.container {
flex-wrap: wrap;
}flex-flow
The flex-flow property is a shorthand for flex-direction and flex-wrap:
/* Lays the items out in a row and over several lines */
.container {
flex-flow: row wrap;
}justify-content
The justify-content property sets how items are aligned on the horizontal axis (x) of a flex container. The possible values are flex-start, center, flex-end, space-between, space-around and space-evenly. The default is flex-start.
/*aligns the items on the left edge*/
.container {
justify-content: flex-start;
}
/*centres the items*/
.container {
justify-content: center;
}
/*aligns the items on the right edge*/
.container {
justify-content: flex-end;
}
/*spreads the items evenly between
the left and right edges with no space at the edges*/
.container {
justify-content: space-between;
}
/*spreads the items evenly between the left edge
and the right edge with the same amount of space at both edges*/
.container {
justify-content: space-around;
}
/* spreads the items evenly between the left edge
and the right edge with the same amount of space at both edges and
between each item */
.container {
justify-content: space-evenly;
}align-items
The align-items property sets how items are aligned on the vertical axis (y) of a flex container. The possible values are flex-start, center, flex-end, baseline and stretch. The default is stretch.
/* Align every item at the top */
.container {
align-items: flex-start;
}
/* Align every item in the middle */
.container {
align-items: center;
}
/* Align every item at the bottom */
.container {
align-items: flex-end;
}
/*makes the items match the height of their content*/
.container {
align-items: stretch;
}align-content
The align-content property is similar to align-items, but it acts on the lines of a multi-line flex container. It accepts the same values as align-items, plus space-between, space-around and space-evenly to distribute the lines.
align-content: flex-start;
align-content: center;
align-content: flex-end;
align-content: space-between;
align-content: space-around;
align-content: space-evenly;
/*aligns the items on the left edge*/
.container {
justify-content: flex-start;
}
/*centres the items*/
.container {
justify-content: center;
}
/*aligns the items on the right edge*/
.container {
justify-content: flex-end;
}
/*spreads the items evenly between the
left and right edges with no space at the
edges*/
.container {
justify-content: space-between;
}
/*spreads the items evenly between the left
and right edges with the same amount of space at
both edges*/
.container {
justify-content: space-around;
}
/* spreads the items evenly between the left
and right edges with the same amount of space at both
edges and between each item */
.container {
justify-content: space-evenly;
}order
The order property sets the display order of the items in a flex container. It takes an integer, and the default value is 0.
<div class="container">
<div class="item first">1</div>
<div class="item second">2</div>
<div class="item third">3</div>
<div class="item fourth">4</div>
<div class="item fifth">5</div>
</div>.container {
display: flex;
}
/*puts item 1 first*/
.first {
order: -1;
}
/*puts item 3 second*/
.third {
order: 2;
}
/*puts item 5 last*/
.fifth {
order: 3;
}
With this code, the items are displayed in the order: 1, 3, 2, 4, 5
Every item that has an order value is sorted by that value, and items without one fall back to 0. Items with negative values are displayed before items with positive ones.
Play with these values until you get the layout you want. Note that the order in which the CSS properties are declared in the file has no effect on the display order: order is the only thing that controls it.
flex-grow, flex-shrink and flex-basis
The flex-grow, flex-shrink and flex-basis properties set the size of the items in a flex container.
flex-growsets the share of the available space each item should take.flex-shrinksets how much an item should shrink to fit into a smaller container.flex-basissets the base size of an item, beforeflex-growandflex-shrinkcome into play.
flex-grow: 1;
flex-shrink: 1;
flex-basis: 200px;
/* makes the item take up
all the available space */
.item {
flex-grow: 1;
}
/* makes the item shrink
to fit a smaller container */
.item {
flex-shrink: 1;
}
/* sets a base size of 200px for an item */
.item {
flex-basis: 200px;
}You can combine the three with the flex shorthand
/* flex: flex-grow | flex-shrink | flex-basi */
.item {
flex: 1 1 200px;
}Examples
Example 1: a grid built with Flexbox
<div class="container-flex">
<div class="item-flex item1">1</div>
<div class="item-flex item2">2</div>
<div class="item-flex item3">3</div>
<div class="item-flex item4">4</div>
<div class="item-flex item5">5</div>
<div class="item-flex item6">6</div>
<div class="item-flex item7">7</div>
<div class="item-flex item8">8</div>
<div class="item-flex item9">9</div>
</div>.container-flex {
display: flex;
flex-wrap: wrap;
/* lets the items be spread over
several lines when there is not enough room */
justify-content: space-between;
/* spreads the items evenly
between the left and right edges with no space
at the edges */
align-content: space-between;
/* spreads the lines evenly between
the top and the bottom with no space at the edges */
}
.item-flex {
text-align: center;
flex: 1 0 calc(33.33% - 20px);
/* uses flex-grow and flex-basis to spread the
items over a 3-column grid using
33.33% of the available width and
20px less space between each item */
}
The flex property decides how items adapt to the space available in the flex container. Here we use flex: 1 0 calc(33.33% - 20px); to lay the items out on a three-column grid, each item taking 33.33% of the available width minus the 20px of space between items. The result is a responsive grid that follows the size of the window on its own.
Combine justify-content, align-content and flex and you can build flexible, adaptive layouts for whatever your page needs. These properties mix in many different ways, so experiment until you find the combination that fits your project.
Example 2: a responsive menu
<nav class="menu-container">
<a href="#" class="menu-item">Home</a>
<a href="#" class="menu-item">About</a>
<a href="#" class="menu-item">Services</a>
<a href="#" class="menu-item">Contact</a>
</nav>.menu-container {
display: flex; /* turns on the flex layout */
justify-content: space-between; /* pushes the menu items to the right and to the left */
align-items: center; /* centres the menu items vertically */
}
/* Adds a menu button for small screens */
.menu-container::before {
content: "Menu"; /* Text shown on the button */
display: none; /* hides the button by default */
}
/* When the screen is narrower than 600px */
@media (max-width: 600px) {
.menu-container {
flex-wrap: wrap; /* Lets the items wrap onto several lines */
justify-content: center; /* Centres the items horizontally */
}
.menu-item {
flex-basis: 100%; /* Takes the full available width */
text-align: center; /* Centres the text */
}
.menu-container::before {
display: block; /* Shows the menu button */
}
}In this example the menu is laid out horizontally, pushed to the left and to the right on wider screens (the default). On small screens (under 600px wide) the items are centred and wrap onto several lines, and a “Menu” button appears to open and close the menu with JavaScript or the tool of your choice. If you want a more detailed example of a Flexbox menu, I wrote a whole article on the subject.
Conclusion
The CSS Flexbox module makes flexible, adaptive layouts for your HTML elements straightforward. Properties such as display, justify-content, align-items and flex let you align and organise the items of a flex container efficiently.
Flexbox is particularly good for content grids, menus and responsive forms, because it hands out the available space according to what the layout actually needs. It is no cure-all for every layout problem, but it solves plenty of common ones. It is often used alongside other layout technologies such as Grid Layout, or layout frameworks such as Bootstrap.
Flexbox is a powerful tool for web developers building flexible, adaptive layouts for websites and applications. Understanding its properties and its basic uses is what gets the most out of it. And check the browser support limits before you ship it in a project.
That compatibility can be automated at build time: PostCSS adds vendor prefixes from the browser list you target. The setup is covered in the Webpack 5 guide, along with the last 2 versions trap, which drags Internet Explorer back in and bloats your CSS with dead prefixes.


