Image for post
Image for post

Flex can be used to slice and dice your site UI into a responsive layout with relative ease if you know all the right properties!

Flex layout consists of two primary element types: container and items.

Image for post
Image for post

To enable Flex box apply display: flex to your HTML element.

There is also display: inline-flex if you want flex container itself to be inline.

Let’s take a closer look at the item. It’s important to understand the difference between align of items within Flex container and align of item content.

Flex can align items or plain text content

Text or non-element items inside HTML elements are known as its content.

Image for post
Image for post

Can the item itself gracefully become a flex container for its own children? Sure! But it works for plain content.

This means now that the item is display: flex you don’t have to use hacks like line-height to center text vertically inside flex item.

If item has no HTML elements its content itself is counted as an5 item. In many cases it’s often basic text, a single word, an image or emojis.

You can turn flex items into flex containers.

Items sometimes contain content, not more items. In that case properties justify-items and justify-content apply to content itself.

flex-direction: column (or row)

You can define the directional flow of items within parent container.

flex-direction: row

This is the default setting.

Image for post
Image for post

flex-direction: row

This is the default setting.

Image for post
Image for post

flex-direction: column

To make items flow down the column change flex-direction to column:

Image for post
Image for post

Green examples above show what happens when item width and height are not set. There is also flex-direction: column-reverse.

You can guess what it does:

Image for post
Image for post

We’ll take a look at it in more detail later in this tutorial with a practical example.

Understanding flex-start and flex-end

Note: flex-start (blue) can refer to either left or top boundary of the container element and flex-end can refer to either bottom or right boundary depending on whether flex-direction property is set to row or column.

Image for post
Image for post

Style applied to this element is:

display: flex;
flex-direction: row; /* default */

Setting flex-direction to column flex-end becomes the bottom boundary.

Image for post
Image for post

Style applied to this element is:

display: flex;
flex-direction: column;

This is where it gets tricky.

Note diagram below shows the same flex container with flex-direction: column; Here also flex-start and flex-end change context based on what axis you are thinking of.

Image for post
Image for post

All of the above is for flex-direction: column. If you switch to flex-direction: row, justify-content and align-items will swap.

Center All Content

Even though Flex is often used to align multiple items one super common align use case you will encounter is applying both vertical and horizontal centering to a single item within a Flex container.

Image for post
Image for post
Centering items vertically within a flex container based on its height is achieved by setting align-items: property to center.

The style applied to the container and item elements above:

display: flex;
justify-content: center;
align-items: center;

Multiple Items

If you just keep adding items flex will automatically resize them based on relative size of all items — even if items were originally set to a height and width. In this example they were set to width=125px and height=125px but notice that they got squeezed:

Image for post
Image for post

flex-wrap: wrap

If you want the items to “drop” to the next row add flex-wrap: wrap

Image for post
Image for post

In this example I also set height: auto to main flex container. (Otherwise the items would have moved down the row but overlap the container and appear “above it.”) Here width and height of each item is set to 125px just like in previous example. Flex will automatically calculate space between items no matter how many there are.

CSS

/* flex */
.flex { display: flex }
/* default */
.row { flex-direction: row }
/* column direction class */
.col { flex-direction: column }
/* center all items vertically and horizontally*/
.center { justify-content: center; align-items: center }
/* center everything inside an item too */
.item { display: flex; justify-content: center; align-items: center }
.item { width: 125px; height: 125px }
/* dashed border around item's content */
.dashed { border: 2px dashed #CCC; padding: 5px }

HTML

<div class = "flex row center">
<div class = "item"><span class = "dashed">1</span></div>
<div class = "item"><span class = "dashed">2</span></div>
<div class = "item"><span class = "dashed">3</span></div>
<div class = "item"><span class = "dashed">4</span></div>
<div class = "item"><span class = "dashed">5</span></div>
</div>

This code will produce following output:

Image for post
Image for post

Here justify-content: center and align-items: center center entire set of items.

justify-content

Let’s skip align-items for now and focus just on the justify-content property.

flex-start

Image for post
Image for post

The justify-content property has 7 values that produce similar proportion. But each subtle difference may be more suitable in a particular case depending on the layout.

space-between

Image for post
Image for post

space-around

Image for post
Image for post

space-evenly

Image for post
Image for post

center

Image for post
Image for post

flex-end

Image for post
Image for post

justify-content works in the same way with flex-direction: column.

To fully understand flex, images are not enough.

What does flex really do?

As the name suggests flex will literally flex your content like a muscle!

But how can this be understood in the least amount of screen space?

To get a better idea of how justify-content really works I created this animation.

Image for post
Image for post

Note: space-around 1 and space-around 2 both use space-around value. The difference is 2ND one has an item with a width set to a value. There is an important flex lesson to learn here: Flex calculates relative percentages automatically. You can see when width is at its narrowest all items gracefully re-scale to the same width.

Multiple Rows

You can align items vertically in the same way.

Image for post
Image for post

Note that in this case we’re still using justify-content, not align-items. That’s because justify-content changes direction in response to value in flex-direction.

align-items

Align items is responsible for aligning items on axis opposite to justify-content. All the same property values apply as justify-content.

Making a Grid in Flex

To make a grid using flex we need to learn how to think about rows and columns. Usually this is achieved by wrapping flex items at a certain interval.

Multiple Columns And Rows

Pure flex layouts can also achieve grid-like behavior. In order to do this you may want to do the following:

  1. Use the flex-wrap:wrap and
  2. Set item’s width and height:

CSS

#parent {

display: flex;
width: 500px; height: 500px;
justify-content: space-evenly;
align-items: center;
flex-wrap: wrap;
}
.item {
width: 80px;
height: 80px;
}

HTML

<div id = "parent"><div class = "item"><span class = "dashed">A</span></div>
<div class = "item"><span class = "dashed">B</span></div>
<div class = "item"><span class = "dashed">C</span></div>
<div class = "item"><span class = "dashed">D</span></div>
<div class = "item"><span class = "dashed">E</span></div>
<div class = "item"><span class = "dashed">F</span></div>
<div class = "item"><span class = "dashed">G</span></div>
<div class = "item"><span class = "dashed">H</span></div>
<div class = "item"><span class = "dashed">I</span></div>
</div>

And here is what the code above will produce:

Image for post
Image for post

Given the size of each item you just have to figure out how much space required to fit a number of them vertically or horizontally and then adjust the parent accordingly.

Multi-directional “float”

In pre-flex era we used float property with values left and right. Then, to align content vertically we used a hack called line-height and sometimes vertical-align.

We can forget about float now. Using flex you can “float” an item by aligning it not only with left or right borders but in any direction.

This is an important use case for creating containers for pop-up chat or notification messages and changing their location to any of the screen corners.

Image for post
Image for post

Light gray values are defaults they are assumed and don’t need to be specified.

Flex Analytics Bar Charts

I found flex to be useful for making analytics charts.

Here is a single bar example. Apply .bar class to each item in main container:

Image for post
Image for post

Source for bar height comes from a statistics source. This could be website traffic.

I used JavaScript’s Math.sin formula to create a wavy chart just to demonstrate it:

Image for post
Image for post

You still have to generate height of each bar by other means other than CSS.

Here is the setup:

CSS

/* main flex container */
.flex { display: flex; }
/* bar container */
.bar { display: flex; flex-direction: column-reverse; height: 200px; }
/* default dimensions of each sub-bar */
.bar div { width: 10px; height: 10px }
/* color coding */
.green { background: yellow }
.orange { background: orange }
.orangered { background: orangered }
.red { background: red }
/* preset heights just for testing */
.ten { height: 10px !important }
.twenty { height: 20px !important }
.thirty { height: 30px !important }
.fourty { height: 40px !important }

HTML

<!-- Statistics Bars -->
<div class = "flex row">

<div class = "bar">
<div class = "red fourty"></div>
<div class = "orangered thirty"></div>
<div class = "orange twenty"></div>
<div class = "yellow ten"></div>
</div>

<div class = "bar">
<div class = "red fourty"></div>
<div class = "orangered thirty"></div>
<div class = "orange twenty"></div>
<div class = "yellow ten"></div>
</div>

<div class = "bar">
<div class = "red fourty"></div>
<div class = "orangered thirty"></div>
<div class = "orange twenty"></div>
<div class = "yellow ten"></div>
</div>

<-- More bars here -->

</div>

Here is another example based on real site traffic data fetched from a server:

Image for post
Image for post

You get the idea. Align items to the bottom and color-code them.

Media Queries

I first learned about Media Queries when I was learning CSS grid. But nothing is stopping you from using media queries with flex.

@media only screen and (max-width: 1000px) {
div.flex {
/* flex values for resolution width 1000px or less */
}
}
@media only screen and (max-width: 800px) {
div.flex {
/* flex values for resolution width 800px or less */
}
}
@media only screen and (max-width: 600px) {
div.flex {
/* flex values for resolution width 600px or less */
}
}

Interactive Flex Editor

Flex automatically re-scales item width and spacing between them based on the relative width of surrounding items. This is at the very core of thinking visually when creating your own layouts. To demonstrate it visually:

Image for post
Image for post

Are you teaching flex visually and need a fun interactive flex editor? Then perhaps you can visit flex editor tool I created in JavaScript. Allegedly it has been used in online class rooms. And it now also comes in dark mode.

Image for post
Image for post

In Conclusion

Flex is a layout toolset that provides more CSS properties to help you slice and dice your UI into responsive areas. This tutorial made attempt to show few commonplace use cases for crafting something concrete with flex.

Get My Coding Books — Limited Time Offer

The diagrams in this tutorial were influenced directly by the manuscript!

All diagrams were taken from my CSS Visual Dictionary book.

You can get it here bundled together with JavaScript Grammar.

Or you can just follow me on Twitter where I share more of my tutorials.

You can also follow me on Twitter where I post my tutorials.

Written by

Issues. Every webdev has them. Published author of CSS Visual Dictionary https://amzn.to/2JMWQP3 few others…

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store