Flexbox Layout

Flexbox lets you build flex-ible layouts!

Flex-box Basics

Flex-box

By default flexbox positions elements within a single row. Note how all divs within the row are distributed equally and have the same width.

.flexbox-container{
    display: flex;
}
.box{
    width: 200px;
    height: 200px;
    margin: 10px;
}

<div class="flexbox-container">
    <div class="box orange">1</div>
    <div class="box darkcyan">2</div>
    <div class="box darkolivegreen">3</div>
    <div class="box cyan">4</div>
    <div class="box lightpink">5</div>
</div>

1
2
3
4
5
With all defaults, five flexbox elements evenly distribute themselves within a single row

Flex-box wrap

You can specify the wrapping behavior of the elements within a flexbox container, that is, how the elements should be distributed when, in a normal situation, they wouldn't fit within a single row.

You use the flex-wrap CSS rule and set it to:

  • nowrap for no wrapping (single line)
  • wrap for wrapping behavior as depicted below
  • wrap-reverse for wrapping in the reverse direction (right to left)

.flexbox-container{
    display: flex;
}
.flexbox-container.wrap{
    flex-wrap: wrap;
}
.box{
    width: 200px;
    height: 200px;
    margin: 10px;
}

 <div class="flexbox-container wrap">
    <div class="box orange">1</div>
    <div class="box darkcyan">2</div>
    <div class="box darkolivegreen">3</div>
    <div class="box cyan">4</div>
    <div class="box lightpink">5</div>
</div>



                    
1
2
3
4
5
When we set the wrap property, the elements take their natural width of 200px and jump to the next row.

Flex-box direction

You can also specify the direction in which the different elements within a flexbox container are placed by using the flex-direction property:

  • row, to place the items within a row from left to right
  • column, to place the items within a column from top to bottom
  • row-reverse, as above but from right to left
  • column-reverse, as above but from bottom to top
In sumary, this will determine whether your flexbox elements are placed in columns or rows.

Note that there is a shortcut property flex-flow that allows you to set both flex-direction and flex-wrap at the same time. For instance flex-flow: column wrap

.flexbox-container{
    display: flex;
}
.fixed-height-500{
    height: 500px;
}
.flexbox-container.wrap{
    flex-wrap: wrap;
}
.flexbox-container.column{
    flex-direction: column;
}
.box{
    width: 200px;
    height: 200px;
    margin: 10px;
}
                                    

<div class="flexbox-container column wrap fixed-height-500">
    <div class="box orange">1</div>
    <div class="box darkcyan">2</div>
    <div class="box darkolivegreen">3</div>
    <div class="box cyan">4</div>
    <div class="box lightpink">5</div>
</div>












                                    
1
2
3
4
5
Instead of the default direction, the flexbox container now uses column. This makes the flexbox elements flow from top to bottom in columns instead of rows. Since have set the width of the parent element to 500 and flex-wrap to wrap the elements that do now fit jump to the next column.

Flex-box Order

With the order CSS property you can specify the order in which each flexbox element appears explicitely:

.flexbox-container{
    display: flex;
}
.first{
  order: 1;
}
.second{
  order: 2;
}
.third{
  order: 3;
}
.fourth{
  order: 4;
}
.fifth{
  order: 5;
}
.box{
    width: 200px;
    height: 200px;
    margin: 10px;
}
                                

<div class="flexbox-container">
    <div class="box orange fourth ">1</div>
    <div class="box darkcyan third">2</div>
    <div class="box darkolivegreen fifth">3</div>
    <div class="box cyan second">4</div>
    <div class="box lightpink first">5</div>
</div>













                                    
                    
1
2
3
4
5
The order property overrides the natural order of the elements.

Flex-box Automatic Sizing and Space Distribution

The flex CSS property lets you specify how the space should be distributed amongst the different flexbox items in relative terms. For instance, if you have two elements and set flex: 2; for the first one and flex: 1; for the second one, the first element will take double the amount of space (width or height based on whether flexbox direction is row or column).

If no flex property is set then the flexbox elements will just take their normal space. (Their specific width/height based on width or height or their contents)

The flex property is actually a short-hand syntax for flex-grow, flex-shrink and flex-basis which determines how flex elements can grow, shrink if allowed and their default size respectively.

.flexbox-container{
    display: flex;
}
.fill{
    flex: 1;
}
.fillx2{
    flex: 2;
}
.box{
    width: 200px;
    height: 200px;
    margin: 10px;
}
                                    
            


<div class="flexbox-container">
    <div class="box orange fill">1</div>
    <div class="box darkcyan fillx2">2</div>
    <div class="box darkolivegreen ">3</div>
</div>









                                    
                    
1
2
3
The element in the middle takes up two times the size of the other two elements

Flexbox Alignment

Flexbox is very flexible when it comes to the alignment of its elements and allows you to align elements in the direction items flow (i.e row - left/right), in the direction perpendicular to how items flow (i.e. row - up/down) and also configure how multiple flexbox rows/columns should align with respect to each other

Aligning Items in the Flow Direction

You can align the items within your flexbox container by using the justify-content rule. This will let you align the different elements:

  • at the beginning flex-start (default), or at the end flex-end
  • centered with center
  • with the same amount of space in between elements space-between
  • with the same amout of space in between and around elements space-around

.flexbox-container{
    display: flex;
}
.flexbox-container.flow-direction-centered{
    justify-content: center;
}
.box{
    width: 200px;
    height: 200px;
    margin: 10px;
}
.box.smaller{
    width: 100px;
    height: 100px;
}

<div class="flexbox-container flow-direction-centered">
    <div class="box orange">1</div>
    <div class="box darkcyan">2</div>
    <div class="box darkolivegreen">3</div>
    <div class="box cyan">4</div>
    <div class="box lightpink">5</div>
</div>






                                    
                    
1
2
3
4
5
The different elements are centered in the flow direction with justify-element as center. In this case the flow direction is row and therefore the appear centered horizontally.
1
2
3
4
5
The different elements are aligned towards the end of the flow direction with justify-element as end. In this case the flow direction is row (flow from left to right) and therefore they appear aligned to the right.

Aligning Items in the Flow Perpendicular Direction

The align-items CSS rule you can determine whether elements align:

  • at the start flex-start, or
  • at the end flex-end,
  • whether they are center aligned center,
  • baseline aligned, that is based on their content baseline,
  • or if they stretch stretch (default)

This finally provides a good way to achieve centering an element in height.

.flexbox-container{
    display: flex;
}
.flexbox-container.centered{
    align-items: center;
}
.box{
    width: 200px;
    height: 200px;
    margin: 10px;
}

<div class="flexbox-container centered">
    <div class="box orange">1</div>
    <div class="box darkcyan">2</div>
    <div class="box darkolivegreen">3</div>
    <div class="box cyan">4</div>
    <div class="box lightpink">5</div>
</div>

                                    
                    
1
2
3
4
5
The different elements are centered in height. I have set a fixed height to the parent container so the aligment it is easier to see
1
2
3
4
5
The different elements are centered at the top.
1
2
3
4
5
The different elements are stretched
1
2
3
4
5
You can override a single element aligment with align-self

Aligning Content form Multiple Rows or Columns

When you have flexbox elements distributed in multiple rows or columns you can use the align-content CSS rule to determine how these multiple rows/columns are aligned in relation to each other. The options available are the same that with the justify-content rule.

.flexbox-container{
    display: flex;
}
.flexbox-container.align-content-start{
    align-content: flex-start;
}
.box{
    width: 200px;
    height: 200px;
    margin: 10px;
}
.box.smaller{
    width: 100px;
    height: 100px;
}
                                    

<div class="flexbox-container wrap aquamarine-nearly-transparent fixed-height-500 align-content-start">
    <div class="box orange">1</div>
    <div class="box darkcyan">2</div>
    <div class="box darkolivegreen">3</div>
    <div class="box cyan">4</div>
    <div class="box lightpink">5</div>
    <div class="box orange">6</div>
    <div class="box darkcyan">7</div>
    <div class="box darkolivegreen">8</div>
    <div class="box cyan">9</div>
    <div class="box lightpink">10</div>
    <div class="box orange">11</div>
    <div class="box darkcyan">12</div>
    <div class="box darkolivegreen">13</div>
    <div class="box cyan">14</div>
    <div class="box lightpink">15</div>
</div> 
                    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
When we have the default flex direction (row/horizontal) and use the option align-content flex-start all rows are aligned in the top part of the flexbox container.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
This time we use the space-between option to distribute the rows to cover the whole flexbox container and leave equal spacing between them.

Example layouts

Flexbox excels at helping you create flexible layouts that gracefully adapt to the viewport of whichever device you're using. Check these example layouts and the description of what I did in each one of them below: