An Introduction to Flexbox in CSS.
Tags: css, webdev, beginners, flexbox
Published: 2020-08-16 17:13:38

CSS is the bane of many developers’ existence, as evidenced by [this query](https://www.reddit.com/r/css/comments/3at81d/why_is_css_so_terrible/) on reddit.

But CSS doesn’t really deserve the bad rap that it gets! Although everybody’s reasoning is different, the general consensus is that CSS is hard because it behaves weirdly. One such concept which scares off most beginners, is that of flexbox. But as you go through this article, it will become apparent to you that flexbox is actually a pretty easy concept to comprehend!

Simply put, flexbox is tool to build layouts. It provides a cross browser-compatible method to implement layouts and makes it easier to add [responsive design](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Responsive_Design) to your application, without you having to explicitly deal with positioning the components of your page.

The only prerequisite to learn flexbox is **CSS selectors**. In case you need to brush up on CSS selectors, you can go through the following article.
{% medium https://medium.com/front-end-weekly/understanding-css-selectors-1c03267e7cd2 %}

<hr>

Just like the [box model](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/The_box_model) in CSS, there is something called the flex model, which can help you visualize the layout a lot better.

The main principle of the flex model is that all its content is laid out along **two axes**, namely a **main axis** and a **cross axis**. By default, the main axis refers to the x-axis or the **horizontal axis**. Likewise, the cross axis refers to the y-axis or the **vertical axis**.

You might be aware that an outer container acts as **parent element**, and all the elements nested within a container will act as **child elements**. In the flex model, this parent element is called a **flex container** and all its children are called **flex items**.

The following image gives a concise explanation of the flex model:

![Illustration of flex model](https://cdn-images-1.medium.com/max/2000/1*M_NAOezsj7UjvtSs5Nn3Pg.png)_Illustration of flex model_

<hr>

Consider the following HTML code, wherein we have a flex container and 4 flex items nested within it.

![Example to illustrate flexbox](https://cdn-images-1.medium.com/max/2000/1*03knBErjlCrorxfrRzkwtw.png)_Example to illustrate flexbox_

Now, if we select `flex-container` and set its `display` property to `flex`, all the default flexbox properties are applied to it, as illustrated below.

![Illustration to show default flex properties](https://cdn-images-1.medium.com/max/2000/1*5cNYjlYwAiDsyCjKhUXhig.png)_Illustration to show default flex properties_

Let’s take a look at the different properties that are applied when an element’s `display` property is set to be `flex` .

-   **flex-direction**:This property sets the direction for the **main axis** and by default, it is set as **row**. The other options include **reverse-row**, **column**, and **reverse-column.** The following image shows the difference between these four values.

![Illustration to show flex-direction](https://cdn-images-1.medium.com/max/2000/1*6ugjQc3_4nnS94f8IJqoVw.png)_Illustration to show flex-direction_

-   **flex-wrap**: Wrapping refers to the process of distributing the flex items over multiple lines. This property is set to **nowrap** by default, as flexbox will try to position all the flex items onto the **main axis**. The options available under this property are **wrap**, **wrap-reverse**, and **nowrap**.

-   **flex-flow:** This is a shorthand property to set the previous 2 properties at once. The order of the properties is flex-flow: flex-direction flex-wrap . The default value is **row nowrap**.

<hr>

Up until now, all the properties I listed were used to either set the direction of the main axis, or to allow flex items to be distributed over multiple lines. The following properties are responsible for the **alignment** of the flex items within the flex container.

-   **justify-content:** This property sets the alignment along the **main axis**. By default, its value is set to **flex-start**. But there are many more options which will help in the construction of the desired layout, as listed below:

![Illustration to explain the different options for justify-content](https://cdn-images-1.medium.com/max/2000/1*TIEKszRwPLu6QrFC_HvDBQ.png)_Illustration to explain the different options for justify-content_

-   **align-items:** This property is used to align the flex items along the **cross axis**. By default, this property is set to **stretch**, which indicates that the flex items will fill the container (along the cross axis, of course). Like the ‘justify-content’ property, this too has other options to align the flex items, as illustrated below.

![Illustration to explain the different options for align-items](https://cdn-images-1.medium.com/max/2000/1*rRfSj0cG98cyWjExPL_KFw.png)_Illustration to explain the different options for align-items_

-   **align-content:** This is used to align the flex-container’s lines within the container, only when there is extra space in the cross-axis. This is similar to justify-content, but it works on an entire line of flex-items, rather than individual items. The following image illustrates the options available in align-content.

![Illustration to explain different options for align-content](https://cdn-images-1.medium.com/max/2000/1*zggWhuDL9EBLfgYcolgnIw.png)_Illustration to explain different options for align-content_

Note that **align-content** will have no effect on your layout in case your main axis has a single line of flex items.

<hr>

Now, let us take a look at the properties that can be applied to the **flex items**, which are nested within the flex container.

-   The ‘**order**’ property is used to override the default order of the flex items. The default is the order in which they appear in the HTML source. Its value can be set using an integer as seen in the image below.

![The flex-items’ order can be seen within the orange boxes](https://cdn-images-1.medium.com/max/2000/1*MIlRe0KDAl5E33IuRSGC4A.png)_The flex-items’ order can be seen within the orange boxes_

-   The **align-self** property is used to set the alignment of individual flex items, along the **cross axis**. This property will override the alignment set by the ‘align-items’ property.

![An example to illustrate align-self](https://cdn-images-1.medium.com/max/2000/1*-wOglEOPyqPH25UAyrzvSQ.png)_An example to illustrate align-self_

The options that are available in this property are the same as those of **align-items** and the default is set as auto .

-   Lastly, there is property called **flex**, which is a shorthand responsible for setting the **flex-grow, flex-shrink** and **flex-basis** properties. You can find a detailed explanation of this sub-property [here](https://css-tricks.com/almanac/properties/f/flex/#:~:text=The%20flex%20property%20is%20a,flex%2Dbasis%20%29%20are%20optional.)

<hr>

Now that you know the basics of flexbox, the next hurdle to overcome is to be able to construct layouts using flexbox.

[This resource](https://tobiasahlin.com/blog/common-flexbox-patterns/) provides examples of some common layouts found in most modern websites.

But, in case you want to be able to build your very own layout, the best method to practise is by converting a PSD template into a CSS file. This means replicating PSD templates using just CSS flexbox! Doing this will help you instantly spot common design patterns which can be achieved using flexbox, which will in turn strengthen your flexbox skills!

A popular resource for Photoshop templates is [dribbble](https://dribbble.com/). You can start by taking a look at [this list of template designs](https://dribbble.com/tags/website_psd_template)

Once you are able to build layouts resembling the above templates, you have already overcome your dread for CSS!

Two very useful resources for diving deeper into other CSS concepts include the [MDN docs](https://developer.mozilla.org/en-US/docs/Web/CSS), and the [css-tricks](https://css-tricks.com/) website.