The Ultimate Guide to Flexbox
- 1. Flexbox overview
- 2. Flexbox Basics
- Main and Cross Axis
- Flex Containers and Items
- 3. Flex Container Properties
- flex-direction
- flex-wrap
- justify-content
- align-items
- align-content
- flex-flow
- 5. Flexbox Examples
- Centering Elements Vertically and Horizontally
- Responsive Navigation Bar with Search
- The Holy Grail Layout
- 6. Other resources
Overview ¶
The Flexbox Layout officially recognized as CSS Flexible Box Layout Module is a new layout mode in CSS3.
Flexbox is a single-dimensional layout, which means that it lays items in one dimension at a time, either as a row, or as a column, but not both together. This can be opposed to the two-dimensional model - CSS Grid Layout, which lays the items in two dimensions simultaneously (rows and columns together).
Flexbox was introduced as an alternative to CSS Floats for setting the overall appearance of a webpage. Flexbox comes with many benefits, in particular, with it you can control alignment, direction, order, and size of items.
The items inside a flex container:
- can be organized in any direction (leftwards, rightwards, downwards or even upwards) (flex-direction).
- can have direct (left-to-right) or reversed (right-to-left) order.
- can have “flex” width and height to fill the available space (flex-item).
- can be set to dynamically collapse or expand along the main axis, and in the meantime preserve the size of the secondary cross axis.
- can be organized linearly along the main axis or wrapped into multiple lines along or across the cross axis.
Flexbox is relatively new, but it enjoys excellent browser support today (nearly 83% of browsers support it).
(Learn more about browser support and compatibility).
Flexbox Basics ¶
When working with Flexbox you need to think in terms of two axes — the main axis and the cross axis, and should differentiate between flex containers and flex items.
Main and Cross Axis
Flexbox is a single-axis–oriented, it has a main axis and cross axis. It means that items are laid either along the main axis or cross axis. The cross axis is always perpendicular to the main one.
The main axis is defined by the flex-direction property, which has the following values:
- row
- row-reverse
- column
- column-reverse
If the flex-direction property is specified with a row or row-reverse values, then your main axis will be horizontal, i.e. run along the row in the inline direction. And the cross axis will run down the columns.
If the flex-direction property is specified with column or column-reverse values, then the main axis will be vertical, i.e. runs from the top of the page to the bottom in the block direction. As for the cross axis, it will run along the rows.
Have a look at this figure to get a better understanding of the concept behind the Flexbox axis.
- main axis- The main axis of a flex container is the main axis along which flex items are placed.
- main-start | main-end - The flex items are laid out within the container starting from main-start and going to main-end.
- main size - A flex item's width or height in the main dimension is the item's main size.
- cross axis - The axis perpendicular to the primary axis in which direction depends on the main axis direction (horizontal or vertical).
- cross-start | cross-end - Flex lines are filled with items and put into the container starting on the cross-start side of the flex container and going toward the cross-end side.
- cross size - The width or height of a flex item in the cross dimension is the item's cross size.
Flex Containers and Items ¶
The flex container is a parent element, which groups a bunch of children elements, flex items. In most cases, the container defines the layout and position of its flex items, however, flex items can be manipulated individually.
To turn an HTML element to Flex container you should use display property with flex (block-level flex container box) or inline-flex (defines inline-level flex container box) values. Otherwise, the browser would ignore all the flexbox properties you used.
.container {
display: flex; /* or inline-flex*/
}
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
display: -ms-flexbox; /* TWEENER */
display: -webkit-flex; /* NEW - Chrome */
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+
Flex Container Properties ¶
The flex-direction property
The flex-direction property is used for creating row and column layouts. It specifies the directions of the flex container’s main axis and sets the order in which items appear.
The flex-direction property has the following values:
- row - items are displayed along the row from left to right.
- row-reverse - items are displayed along the right to left.
- column - items are displayed vertically from top to bottom.
- column-reverse - items are displayed vertically from bottom to top.
Example of the flex-direction property:¶
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
h3 {
color: #8ebf42;
}
.flex-container {
display: flex;
flex-direction: row-reverse;
padding: 30px;
border: 1px dashed #666;
}
.flex-container > div {
width: 80px;
height: 70px;
margin: 5px;
border-radius: 3px;
background-color: #1faadb;
}
</style>
</head>
<body>
<h3>row-reverse</h3>
<div class="flex-container">
<div></div>
<div></div>
<div></div>
</div>
</body>
</html>
In our example, the items are organized in a reversed order. Change values of flex-direction property (row, column, column-reverse) to see how the appearance of the items changes.
The flex-wrap property ¶
By default, all the flex items fit onto one line, and if flex items are too wide for the container, they will overflow it. To prevent this you should use the flex-wrap property to wrap the items.
The property can accept the following values:
- nowrap (default) - flex items are displayed in one line, by default they fit the flex container's width.
- wrap - flex items are displayed in multiple rows if needed from left-to-right and top-to-bottom.
- wrap-reverse - flex items are displayed in multiple rows if needed from left-to-right and bottom-to-top.
The justify-content property ¶
The justify-content property is used to define the horizontal alignment of items along the main axis. It helps distribute free space left between the flex items on the main axis.
The values for justify-content are as follows:
- flex-start (default value) - items are laid out at the beginning of the container.
- flex-end - items are laid out at the end of the container.
- center - items are laid out at the center of the container.
- space-between - items are evenly (with space between them) distributed in the line; the first item is on the start line, the last item on the end line.
- space-around - items are displayed with space before, between, and after.
- space-evenly - items are distributed so that the spacing between any two items (and the space to the edges) is equal.
Example of the justify-content property:¶
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
.flex-container {
display: flex;
padding: 10px;
margin-bottom: 20px;
background-color: #1faadb;
}
.flex-start {
justify-content: flex-start;
}
.flex-end {
justify-content: flex-end;
}
.center {
justify-content: center;
}
.space-between {
justify-content: space-between;
}
.space-around {
justify-content: space-around;
}
.flex-start {
justify-content: flex-start;
}
.flex-container > div {
width: 28%;
height: 45px;
margin: 5px;
border-radius: 3px;
background-color: #8ebf42;
}
.flex-container > div.item-two {
width: 18%;
}
</style>
</head>
<body>
<p>flex-start</p>
<div class="flex-container flex-start">
<div></div>
<div class="item-two"></div>
<div></div>
</div>
<p>flex-end</p>
<div class="flex-container flex-end">
<div></div>
<div class="item-two"></div>
<div></div>
</div>
<p>center</p>
<div class="flex-container center">
<div></div>
<div class="item-two"></div>
<div></div>
</div>
<p>space-between</p>
<div class="flex-container space-between">
<div></div>
<div class="item-two"></div>
<div></div>
</div>
<p>space-around</p>
<div class="flex-container space-around">
<div></div>
<div class="item-two"></div>
<div></div>
</div>
</body>
</html>
Change the value of justify-content property to see how the items are aligned.
The align-items property ¶
The align-items property is used for aligning items along the cross axis. It is just the opposite of justify-content property, which aligns the items along the main axis.
The values for align-items are as follows:
- stretch (default) - items are stretched to fill the container.
- flex-start - items are stacked to the cross start of the container.
- flex-end- items are stacked to the cross end of the container.
- center- items are stacked at the center of the cross axis.
- baseline - items are aligned just as their baselines are aligned.
Example of the align-items property:¶
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
.flex-container {
display: flex;
justify-content: space-between;
align-items: center; /* Use another value to see the result */
height: 250px;
padding: 15px;
background-color: #1faadb;
}
.flex-container > div {
width: 15%;
height: 100%;
border-radius: 3px;
background-color: #8ebf42;
}
.flex-container .one {
height: 60%;
}
.flex-container .three {
height: 40%;
}
.flex-container .four {
height: 70%;
}
</style>
</head>
<body>
<div class="flex-container">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
<div class="four"></div>
</div>
</body>
</html>
In our example, we used center value to center the items in the cross-axis. Try other values and see the result.
The align-content property ¶
The align-content property is used to align a flex container’s lines within the container when there is an extra space in the cross-axis, just as how justify-content aligns individual items within the main axis.
The values for align-content and their meaning are as follows:
- stretch (default) - lines stretch to take up the available space.
- flex-start - lines are grouped to the start of the container.
- flex-end - lines are grouped to the end of the container.
- center - lines are grouped to the center of the container.
- space-between - lines are evenly distributed; the first line is at the start of the container while the last one is at the end.
- space-around - lines are evenly distributed with equal space around each line.
Example of the align-content property:¶
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
.flex-container {
display: flex;
flex-wrap: wrap;
align-content: flex-end/* Use another value to see the result */;
min-height: 250px;
padding: 10px;
background-color: #1faadb;
}
.flex-container>div {
width: 45%;
height: 45px;
margin: 5px;
border-radius: 3px;
background-color: #8ebf42;
}
.flex-container .one,
.flex-container .nine {
width: 23%;
}
.flex-container .two,
.flex-container .six {
width: 9%;
}
.flex-container .three {
width: 25%;
}
.flex-container .four {
width: 35%;
}
.flex-container .five,
.flex-container .eleven {
width: 32%;
}
.flex-container .seven,
.flex-container .ten {
width: 6%;
}
</style>
</head>
<body>
<p>flex-end</p>
<div class="flex-container">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
<div class="four"></div>
<div class="five"></div>
<div class="six"></div>
<div class="seven"></div>
<div class="eight"></div>
<div class="nine"></div>
<div class="ten"></div>
<div class="eleven"></div>
</div>
</body>
</html>
The flex-flow property ¶
This is a shorthand property for flex-direction and flex-wrap individual properties, which define together the main and cross axes of the flex container. The default value is row nowrap.
Example of the flex-flow property:¶
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
.flex-container {
display: flex;
flex-flow: row-reverse wrap; /* Use another value to see the result */
padding: 30px;
border: 1px dashed #666;
}
.flex-container > div {
width: 30%;
height: 70px;
margin: 5px;
border-radius: 3px;
background-color: #8ebf42;
text-align: center;
font-size: 28px;
font-weight: 700;
line-height: 70px;
color: #fff;
}
</style>
</head>
<body>
<div class="flex-container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
</body>
</html>
You can choose another value to see how the position of items changes.
Flex Item Properties ¶
The order property
By default, items are laid out in the order in which they appear in the source code (starting from the lowest numbered ordinal group and going up). To change the order of items in the flex container the order property is used.
The order property sets the order of flex items by assigning them to ordinal groups. It takes a single integer value, which defines the ordinal group the flex item belongs to. The default value is 0.
Example of the order property:¶
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
.flex-container {
display: flex;
flex-flow: row wrap;
padding: 30px;
border: 1px dashed #666;
}
.flex-container > div {
width: 30%;
height: 70px;
margin: 5px;
border-radius: 3px;
background-color: #8ebf42;
text-align: center;
font-size: 28px;
font-weight: 700;
line-height: 70px;
color: #fff;
}
.item-one {
order: 1;
}
.item-four {
order: -1;
}
.item-five {
order: 0;
}
.item-three {
order: 2;
}
</style>
</head>
<body>
<div class="flex-container">
<div class="item-one">1</div>
<div class="item-two">2</div>
<div class="item-three">3</div>
<div class="item-four">4</div>
<div class="item-five">5</div>
</div>
</body>
</html>
The align-self property ¶
The property is used for individually aligning items within the flex container. Flex items are aligned in the cross axis of the flex container’s line (just as justify-content, but in the perpendicular direction). When set the align-self property overrides the alignment specified by align-items.
The align-self property has the same values as the align-items. They are listed below for your convenience.
- stretch (default) - items are stretched to fill the container.
- flex-start - items are stacked to the cross start of the container.
- flex-end- items are stacked to the cross end of the container.
- center - items are stacked at the center of the cross axis.
- baseline - items are aligned such as their baselines are aligned.
Example of the align-self property:¶
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
.flex-container {
display: flex;
justify-content: space-between;
height: 300px;
padding: 10px;
border: 1px dashed #666;
}
.flex-container > div {
width: 15%;
height: 80%;
margin: 5px;
border-radius: 3px;
background-color: #8ebf42;
}
div.item-two {
width: 20%;
}
div.item-three {
align-self: flex-end;
height: 80px;
margin: 0 10%;
}
</style>
</head>
<body>
<div class="flex-container">
<div class="item-one"></div>
<div class="item-two"></div>
<div class="item-three"></div>
<div class="item-four"></div>
</div>
</body>
</html>
The flex-grow property ¶
The flex-grow property defines the ability of an item to grow if necessary. It sets the flex to grow factor (relatively to the rest of the items within a container), which specifies the space that the item should take up in the container when distributing positive space.
The property takes a unitless value that serves as a proportion.
If all items in the container have the same value for flex-grow (for example, 1) than all items have the same size in the container.
If the size of one of the flex items is different (for example, 2), then this item will take up twice more space relative to the size of the other items (the size of which is set to 1).
Example of the flex-grow property:¶
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
.flex-container {
display: flex;
margin-bottom: 20px;
}
.flex-container div {
flex-grow: 0.2;
padding: 30px 5px;
margin-right: -2px;
border: 2px solid #8ebf42;
}
.flex-container div.two {
flex-grow: 5;
}
.flex-container span {
display: flex;
justify-content: center;
align-items: center;
width: 60px;
height: 60px;
margin: auto;
border-radius: 50%;
background-color: #8ebf42;
font-size: 28px;
font-weight: 700;
color: #fff;
}
</style>
</head>
<body>
<div class="flex-container">
<div>
<span>1</span>
</div>
<div>
<span>2</span>
</div>
<div>
<span>3</span>
</div>
<div>
<span>4</span>
</div>
<div><span>5</span>
</div>
</div>
<div class="flex-container">
<div>
<span>1</span>
</div>
<div class="two">
<span>2</span>
</div>
<div>
<span>3</span>
</div>
<div>
<span>4</span>
</div>
<div>
<span>5</span>
</div>
</div>
</body>
</html>
The flex-shrink property ¶
The flex-shrink is set to allow a flex item to shrink. It specifies the space that the item should take up in the container when negative space is distributed.
The property takes a unitless value.
By default, all flex items can be shrunk, but if we set the value to 0 (don't shrink) they will preserve the original size.
Example of the flex-shrink property:¶
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
.flex-container {
display: flex;
}
.flex-container div {
width: 120px;
padding: 30px 10px;
margin-right: -2px;
border: 2px solid #8ebf42;
}
.flex-container div.two {
flex-shrink: 0;
}
.flex-container span {
display: flex;
justify-content: center;
align-items: center;
width: 60px;
height: 60px;
margin: auto;
border-radius: 50%;
background-color: #8ebf42;
font-size: 28px;
font-weight: 700;
color: #fff;
}
</style>
</head>
<body>
<div class="flex-container">
<div>
<span>1</span>
</div>
<div class="two">
<span>2</span>
</div>
<div>
<span>3</span>
</div>
<div>
<span>4</span>
</div>
<div>
<span>5</span>
</div>
<div>
<span>6</span>
</div>
</div>
</body>
</html>
The flex-basis property ¶
The flex-basis property sets the initial size of a flex item before the remaining space is distributed according to the flex factors. The property is specified by the keyword content or width.
The flex-basis values are as follows:
- auto (default) -the length is equal to the length of the flexible item.
- width - an absolute length, or a percentage of the parent flex container's main size property, or the keyword auto. Negative values are invalid.
- content - determines automatic sizing, based on the flex item’s content.
- initial - sets this property to its default value.
Example of the flex-basis property:¶
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
.flex-container {
display: flex;
background-color: #8ebf42;
}
.flex-container div {
padding: 30px 10px;
margin-right: -2px;
border: 2px solid #8ebf42;
background-color: #fff;
}
.flex-container div.four {
flex-basis: 25%;
}
.flex-container span {
display: flex;
justify-content: center;
align-items: center;
width: 60px;
height: 60px;
margin: auto;
border-radius: 50%;
background-color: #8ebf42;
font-size: 28px;
font-weight: 700;
color: #fff;
}
</style>
</head>
<body>
<div class="flex-container">
<div>
<span>1</span>
</div>
<div>
<span>2</span>
</div>
<div>
<span>3</span>
</div>
<div class="four">
<span>4</span>
</div>
<div>
<span>5</span>
</div>
</div>
</body>
</html>
The flex property ¶
The flex property is the shorthand for flex-grow,flex-shrink, and flex-basis together. The flex-shrink and flex-basis are optional.
Among other values, this property can accept auto (1 1 auto) or none (0 0 autos).
Example of the flex property:¶
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
.flex-container {
display: flex;
height: 150px;
padding: 10px;
margin-bottom: 20px;
border: 1px dashed #666;
}
.flex-container > div {
width: 15%;
margin: 5px;
border-radius: 3px;
background-color: #8ebf42;
}
.second > div {
flex: 1;
}
</style>
</head>
<body>
<div class="flex-container">
<div></div>
<div></div>
<div></div>
</div>
<div class="flex-container second">
<div></div>
<div></div>
<div></div>
</div>
</body>
</html>
Flexbox Examples ¶
Let’s have a look at some CSS flexbox examples and see what kind of layouts you can use for your own web projects.
Centering Elements Vertically and Horizontally
Centering elements by all available means in CSS has always been a problem. With the advent of Flexbox, this problem is easily solved. With align-items, align-self, and justify-content properties, you can align elements both vertically or horizontally.
Example of the align-items, align-self and justify-content properties for centering elements vertically and horizontally:¶
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
.flex-container {
display: flex;
justify-content: center;
align-items: center;
height: 200px;
border: 1px dashed #666;
}
.flex-container > div {
width: 70px;
height: 70px;
margin: 5px;
border-radius: 3px;
background-color: #1faadb;
}
</style>
</head>
<body>
<div class="flex-container">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</body>
</html>
Responsive Navigation Bar with Search ¶
Using Flexbox you can create a navigation bar with menu items aligned to the left, and the search bar aligned to the right (or vice versa). The navigation bar is responsive, it expands or collapses depending on the screen size.
Example of the responsive navigation bar:¶
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
.main-nav {
display: flex;
padding: 15px;
border-radius: 5px;
background: #1c87c9;
color: #fff;
font-weight: 500;
}
.main-nav > ul {
display: flex;
flex: 2;
padding: 0;
margin: 0;
list-style-type: none;
}
.main-nav li {
margin-right: 20px;
}
.main-nav > form {
display: flex;
justify-content: flex-end;
flex: 1;
}
.main-nav input {
flex: 1;
padding: 5px;
}
.main-nav button {
padding: 0 20px;
margin-left: 10px;
border: 0;
border-radius: 20px;
background: #fff;
color: #666;
}
@media screen and (max-width: 575px) {
.main-nav {
flex-direction: column;
}
.main-nav ul {
margin-bottom: 10px;
}
}
</style>
</head>
<body>
<nav class="main-nav">
<ul>
<li>Home</li>
<li>About us</li>
<li>Services</li>
<li>Contact us</li>
</ul>
<form>
<input type="search" placeholder="Search">
<button type="button">Go</button>
</form>
</nav>
</body>
</html>
The Holy Grail Layout ¶
The Holy Grail layout pattern is very popular on the web. It includes a header, footer, the main content area with fixed-width navigation on the left, content in the middle, and a fixed-width sidebar on the right.
Example of the holy grail layout:¶
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
* {
box-sizing: border-box;
font-size: 18px;
}
body {
display: flex;
flex-direction: column;
min-height: 100vh;
margin: 0;
}
.main {
display: flex;
flex: 1;
}
.main > article {
flex: 1;
}
.main > nav,
.main > aside {
0 Comments
CAN FEEDBACK
Emoji