CSS Flexbox part 1
Tags: beginners, css
Published: 2019-11-21 19:56:50

---
title: CSS Flexbox part 1
published: true
description: A beginner guide to the CSS Flexbox
tags: beginners, css
series: FrontEnd Development Zero to Hero
---

Achieving specific layouts has been a daunting task in CSS and developers had to result to [hacks](https://tantek.com/CSS/Examples/boxmodelhack.html) to get the job done. It all started with using HTML tables to get a pixel perfect design then the `float` property came around that allow page element to be positioned to the left or right of its parent container, this had effect that were totally undesirable  due to the default behaviors of floated elements.

In search of a solution the [clearfix hack](https://css-tricks.com/snippets/css/clear-fix/) was discovered that allow developers to create layouts like the _Holy grail_. The clearfix hack grew in popularity and even made its way into frameworks like some earlier versions of Bootstrap.

Developers were at ease using frameworks like Bootstrap as it saved them all the headache of designing layouts with raw CSS. But still, there was a need for this to be available natively in CSS.

In the year 2009 the first _Flexbox_ specification was published as a _Working Draft_ on the W3C website. Some of the browser vendors to implement it were Firefox and Webkit with some inconsistencies. In the years that followed changes were made to the specification, a new editor took over, unofficial syntax was published that were supported in Chrome, Opera and Internet Explorer 10.

Between the year 2012 and 2013 the specification changed status from being a _W3C Candidate Recommendation_ to a _Working Draft_ and a new syntax was published in 2015. The current version of the specification as of November 2019 is dated 19th November 2018 and titled _CSS Flexible Box Layout Module Level 1_ and it is a _W3C Candidate Recommendation_ which means it still subject to change and other specifications may supersede it.

Flexbox was designed with one thing in mind _User Interface Design_ of websites and complex applications.

This post will serve as a beginners introduction to what _Flexbox_ (or Flexbox Layout) is all about.  Following the tradition of this series i will be using the [specification]( https://www.w3.org/TR/css-flexbox-1/) in subsequent explanations. Some part of the specification are quite tricky and require you to create a mental model to really get what is going on but I'll do my best to explain and translate the specification.

_Create a blank HTML and CSS files and make sure the CSS is linked with the HTML file. And kindly note that all screenshots are from <b>Firefox 70</b> web browser and its Developer Tools_.

With that out of the way, let's start.

<hr>

In [this series](https://dev.to/ziizium/frontend-development-zero-to-hero-j0j) we've talked about [floats](https://dev.to/ziizium/css-floats-309c), block layout , inline layout and [positioned](https://dev.to/ziizium/css-positioning-34d8) layout. Speaking in terms of computer science these "layouts" are actually [algorithms](https://en.wikipedia.org/wiki/Algorithm) that determine the size and position of boxes based on their relationship with their sibling and ancestor boxes (parent boxes). But you should know these layouts are part of CSS2.1 and Flexbox is part of the modular nature of CSS3 hence the title of the specification _CSS Flexible Box Layout Module Level 1_.

Flexbox layout is similar to block layout and items can be displayed in varying directions using flexbox specific properties unlike block layout where you had to result to properties like `float`, `position`.

I mentioned earlier that some part of the specification is tricky to understand, let's begin by explaining some key flexbox terminologies.

###__FLEXBOX LAYOUT TERMINOLOGY__

Listed below are terms that you will definitely come by when designing web pages using flexbox.

* flex container
* flex item
* main axis
* cross axis

###__flex container__

From the [specification]( https://www.w3.org/TR/css-flexbox-1/#box-model):

> A flex container is the box generated by an element with a computed display of flex or inline-flex. In-flow children of a flex container are called flex items and are laid out using the flex layout model.

This means a flex container is a parent element which has the `display` property value set to `flex` or `inline-flex`. It can have child elements and these child elements are called _flex items_ and they are laid out on screen using flexbox layout model.

Let's take an example. Save the following HTML and CSS.

```html
<div class="parent">
  <p class="child-one">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
  <ul class="child-two">
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
  </ul>
</div>
```
```css
.parent {
  outline: 1px solid blue;     /* Just a cosmetic */
  background-color: #f9f9fa;   /* Another cosmetic */
}
```

Load the HTML file  in your browser.

![A paragraph text and unordered list with a blue border](https://thepracticaldev.s3.amazonaws.com/i/1xhovvfya0qybytsw9r6.png)

What you see in the image above is just the behavior of regular block elements displayed one after the other from top to bottom. Now let's apply the _flexbox layout_.

Update the `.parent` CSS rule with the following:

```css
.parent {
  /* All other properties remain the same */
  
  display: flex;
}
```

Save and refresh. You might be surprised.

![A paragraph text and unordered list with a blue border](https://thepracticaldev.s3.amazonaws.com/i/6paxxdj6q289959of5t9.png)

What just happened? Use "Inspect Element" on an empty part of the box and navigate to the _Layout_ tab.

![A paragraph text and unordered list with a blue border](https://thepracticaldev.s3.amazonaws.com/i/nbb66m1bolm3e81mmblz.PNG)

Observe the image above, you will realize the browser indicate the paragraph (`p.child-one`) and  the unordered list (`ul.child-two`) are _Flex Items_. You can play around by clicking the toggle switch in the _Flex Container_ to see the flex item highlighted on screen.

As a take away from this explanation, update the `.parent` CSS rule by changing `display: flex;` to `display: inline-flex;` and observe the output in the browser. Then use "Inspect Element" on the output and flip the switch in the _Developer Tools_ to see that the elements are truly inline.

![A paragraph text and unordered list with a blue border](https://thepracticaldev.s3.amazonaws.com/i/0olb086ivuunvi5g8bo3.PNG)

###__flex item__

Flex items are the child elements of a flex container as explained earlier.

###__main axis__

The [specification]( https://www.w3.org/TR/css-flexbox-1/#main-axis):
> The main axis of a flex container is the primary axis along which flex items are laid out. It extends in the main dimension. 

This means the main axis is the direction in which the flex items are laid out. This can be from left to right or top to bottom. The starting point in this direction is called the _main start_ and the ending part is called the _main end_. In mathematics this can be the x or y axis on a graph.

###__cross axis__

This is the area that is perpendicular to the _main axis_. The word "perpendicular" means opposite in direction. This means if the _main axis_ runs from left to right, the _cross axis_ will run from top to bottom. But it gets tricky.

The image below summarize the default behavior of a flex container.

![Main and Cross axis of the Flexbox layout](https://thepracticaldev.s3.amazonaws.com/i/blwmf2mmrqmppx8lsuju.png)
<figcaption>CSS Flexible Box Layout Module Level 1</figcaption>

Remember i said:

> _main axis_ runs from left to right and the cross axis will run from top to bottom

This is the default behavior but the tricky part is: If the image is turned in the vertical direction the _main axis_ will run from top to bottom and the _cross axis_ will run from left to right. Which is the opposite of what i said earlier. 

Observe the image below.

![Main and Cross axis of the Flexbox layout](https://thepracticaldev.s3.amazonaws.com/i/c0eohawgqz01builw25f.png)
<figcaption>CSS Flexible Box Layout Module Level 1</figcaption>

Now the question is: _How can we change the direction?_. We'll have to talk about properties that have to do with direction in a flex container. 

###__FLEX PROPERTIES: DIRECTION__

These properties are:

* `flex-direction`
*  `flex-wrap`
* `flex-flow`
* `order`

###__`flex-direction`__

From the [specification]( https://www.w3.org/TR/css-flexbox-1/#propdef-flex-direction):

> The flex-direction property specifies how flex items are placed in the flex container, by setting the direction of the flex container’s main axis. This determines the direction in which flex items are laid out.

* `row`
* `row-reverse`
* `column`
* `column-reverse`

The name of this values are self descriptive. Let's jump to some code.

We are still using the code from the previous explanation. Add the following cosmetic code to the `ul` and `p` element and make sure the `display` property on the `.parent` is still `flex`.

```css
p {
  outline: 3px solid red;
}

ul {
  outline: 3px solid magenta;
}
```

Save and refresh your browser.

![Text with red and magenta colored borders](https://thepracticaldev.s3.amazonaws.com/i/h9x2dwhnvu7jmdso6o4k.PNG)

Now lets change the direction. Update the `.parent` CSS rule with the following:

```css
.parent {
  /* All other properties remain the same */

  flex-direction: column;    /* Add this */
}
```

Save and refresh. The direction of the content changed. Take note of the highlighted part.

![Text with red and magenta colored borders](https://thepracticaldev.s3.amazonaws.com/i/ae2xluib8odkiys9zig4.PNG)

How about we reverse the layout? . Update the `.parent` CSS rule with the following:

```css
.parent {
  /* All other properties remain the same */

  flex-direction: column-reverse;    /* Update with the new value */
}
```

Save and refresh your browser to see the changes.

![Text with red and magenta colored borders](https://thepracticaldev.s3.amazonaws.com/i/0xy0eqs945xsy4786qiv.PNG)

The `row` value is the default value and I'll leave you to have fun with `row-reverse`.

###__`flex-wrap`__

This property control if the flex container can span a single or multiple line.

__Delete__ the `flex-direction` in the `.parent` CSS rule and add the following:

```css
.parent {
  /* All other properties remain the same */

  flex-wrap: wrap;    /* Add this */
}
```

Save and refresh. You might not see the changes until you resize your browser window or the _Developer Tools_. In the image below i resized the _Developer Tools_.

![Text with red and magenta colored borders](https://thepracticaldev.s3.amazonaws.com/i/arksqgxqcx7km89tecwy.PNG)

The `wrap-reverse` will do the opposite.

![Text with red and magenta colored borders](https://thepracticaldev.s3.amazonaws.com/i/le1x1ow5kjatkfc63gqs.PNG)

Using the `no-wrap`  value the flex items will not wrap into multiple lines and will remain on a single line.

###__`flex-flow`__

The `flex-flow` property is a shorthand for setting the `flex-direction` and `flex-wrap` properties, which together define the flex container’s _main_ and _cross axes_.

```css
.selector {
  /*
   * 1. flex-direction
   * 2. flex-wrap
  */
             /*1*/  /*2*/
  flex-flow: column wrap;
}
```

###__`order`__

Flex items are displayed and laid out in the order they appear in your document.

The default value for the `order` property is `0`. Now let's have some fun.

In our HTML file the paragraph comes before the unordered list. Which means if we start counting from number one upwards, the paragraph will be one, the unordered list will be two.  The `order` property can be used to change this ordering.

Add this to the `p` CSS rule. Don't forget to save your file before refreshing your browser. 

```css
p {
  /* All other properties remain the same */

  order: 2;   /* Add this*/
}
```

We gave the paragraph an `order` value of `2`, with this it will appear after the unordered list when the page is rendered.

![Text with red and magenta colored borders](https://thepracticaldev.s3.amazonaws.com/i/jcr2vh1yebn0363glerp.PNG)

The `order` property also accepts a negative integer. If you __delete__ the `order: 2;` from the `p` CSS rule and update `ul` with the code below you will get the same result.

```css
ul {
  /* All other properties remain the same */

  order: -1;   /* Add this*/
}
```

If you have multiple page elements in the following order in your HTML document: `header`, `main`, `article` `footer` you can use the `order` property to make the `footer` appear before the `header` when the page is rendered.

<hr>

In the [Second part](https://dev.to/ziizium/css-flexbox-part-2-18f2) of this post we will continue with the following subheadings:

* FLEXBOX PROPERTIES: Flexibility
* FLEXBOX PROPERTIES: Alignment