CSS flex-box Guide for anyone
Tags: css, webdev, html, tutorial
Published: 2021-10-22 13:10:51

## ❓ What is flex?

flex is a CSS3 property. It is used for creating the layout and manage the content placement.

Before flex, the only way to create layouts was either using 'floats', 'tables', or 'positions'.

## 👍 floats, tables, and positions, vs flex :

1. Working with Floats and positions was challenging. Due to clearing the floats, handling different resolutions, and devices.
2. Layouts with floats and positions were hard to manage.
2. Lot of code to meet same designs for cross browsers, OS, platforms, resolutions, etc.
3. Creating responsive designs required extra effort.
4. Cross-browser support was the pain.

## 📝 Important Concepts

1. Axis - main and cross
2. Row and Column
3. Parent (container) and Children (items)
3. Wrap 
4. Basis 
5. Order
6. Gap
7. Grow & Shrink
8. Justify-content, Align-items and Align-content
9. Grids vs flex

## 💫 axis and flex

To understand how flex works and the properties associated with it we need to first understand the concept of `axis`.

In flex we have 2 axis - `main` and `cross`. Cross axis is dependent on the main-axis. Cross-axis is always perpendicular to the main-axis.

What is main-axis? Main-axis is define based on the `direction` of the flex. If the direction is `row` then the `main-axis` will be x-axis (horizontal). If it is `column` then the `main-axis` would be y-axis(vertical). Now, based on the main-axis, cross-axis will be changed.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2d8petvv6y8p90gma7vi.png)

In the below image you can see the cross-axis is always perpendicular to the main-axis. So, when `main-axis` is  `x-axis` then `cross-axis` is `y-axis` and vice-versa.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lcaqr4jbgvzhwvkrocn8.png)


## 👍 Defining flex

To use flex we need to use the `display: flex`. The container with `display:flex` become the parent and the direct elements inside it will be called children or items.

> default `flex-direction` value is row. We are going to learn about flex-direction soon.

Eg:

```HTML
<section>
  <div>One</div>
  <div>Two</div>
</section>
```

```CSS
section {
   display: flex;
}
```

When we declare any container as `flex` `flex-direction` auto declared with the value set to the `row`.

💻 [Code](https://github.com/Neha/css-flex-box/tree/master/flex)

| property  |  values | 
|---|---|
| display  | flex, inline-flex |     
  

## 👍 Row and column

In flex we can have either row or column. We cannot have both. This is the huge difference between grids and flex. Flex is 1 Dimensional. Row and column are the backbone and feature(s) of the flex. This helps in creating the layout, arranging the content. You will see with examples as we move ahead.

We use the property `flex-direction` to define row/column.

```HTML
<section>
  <div>One</div>
  <div>Two</div>
</section>
```

```CSS
section { 
 display: flex;
 flex-direction: column; 
}
```

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iimg55fdb361lwzyiaa3.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ubfbivjdh9kf9rthjxtu.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ylkzeaaojse5zwzd5sym.png)

In `flex` we can reverse the row and column by using just one property `row-reverse` and `column-reverse`. This is an easy way to achieve complex designs but this would be only the visual change there won't be any DOM changes. Hence, it is important to think about the accessibility side-effects.

💻 [Code - row](https://github.com/Neha/css-flex-box/tree/master/row)

💻 [Code - row-reverse](https://github.com/Neha/css-flex-box/tree/master/row-reverse)

💻 [Code - column](https://github.com/Neha/css-flex-box/tree/master/column)

💻 [Code - column-reverse](https://github.com/Neha/css-flex-box/tree/master/column-reverse)

| property  |  values | 
|---|---|
| flex-direction  | row, column, row-reserve, column-reserve |     
  
## 👍 wrap

While working with row and column. It is common to see items are overflowing from the flex container especially when the items are more than the container's width or height. 

We can wrap (moving the items to the next row or column automatically) by using the property `flex-wrap`. This will not let the items flow out of the container. 

`wrap` property is highly used especially when the content is dynamic. 

The default value is `no-wrap`.

```HTML
<section>
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
</section>
```

```CSS
section{ 
 width: 500px;
 display: flex; 
 flex-direction: row; 
 flex-wrap: wrap; 
}

section > div{
 width: 200px;
}
```

![flex no-wrap](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0fwxzbsyuen9yyqqi395.png)

![flex wrap](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lb3k75f7xbjdkiralch6.png)

💻 [Code](https://github.com/Neha/css-flex-box/tree/master/wrap)

| property  |  values | 
|---|---|
| flex-wrap  | no-wrap, flex-wrap, wrap-reverse |


### Responsive

Another advantage of flex is the ease of working with responsive designs. Code-writing and managing responsive designs with flex is easier. 

1) We don't need to change the DOM as per the screen size. By just changing one property `flex-direction` we can make the items stack or spread. A common design pattern for the responsive design.

2) We can use the available space to adjust the items (explained below)

We learned earlier that by using `flex` we can make the element behave as either columns or rows.  Now, we can control how the items should behave as per the available space in the container.

![available space](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4l25rtv2didspdca9pff.png)

## 👍 grow and shrink

`grow` and `shrink` expand and contract the items (flex-children) as per the available space in the container (parent flex element).

Elements generally take the width as per the content. The width are fixed and they are not scalable as per the space available on the screen/resolution. In such cases, grow and shrink helps in scaling the elements as per the space available.

Grow and Shrink accepts numeric value (positive integer) and the items will grow accordingly.

>> Shrink and grow accept value as a positive integer. 1 means equal space.

```HTML
<section>
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
</section>
```

```CSS
section {
  display: flex;
  background: #e4f8ff;
  padding: 10px;
  width: 800px;
  flex-direction: row;
  flex-wrap: wrap;
}

section > div {
  background: #dfffdf;
  padding: 10px;
  border: 1px solid #fff;
  width: 50px;
  flex-grow: 1;
}
```


```HTML
<section>
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
</section>
```

```CSS
section {
  display: flex;
  background: #f8ffe7;
  padding: 10px;
  width: 100%;
  flex-direction: row;
  flex-wrap: wrap;
}
section > div {
  background: #dfffdf;
  padding: 10px;
  border: 1px solid #fff;
  flex-basis: 100px;
  flex-shrink: 1;
}

@media only screen and (min-width: 600px) {
  section {
    width: 800px;
    flex-wrap: wrap;
  }
  section > div {
    background: #dfffdf;
    padding: 10px;
    border: 1px solid #fff;
  }
}
```

💻 [Code](https://github.com/Neha/css-flex-box/tree/master/shrink)

## 👍 flex-basis

`flex-basis` is to set the size of the item. By default, it would be auto which means content size.  If there is width declared on the item then the `flex-basis` value would be respected.

>> If we are using size we can drop width. Ideally, when working with flex we should use size over width.  
                                                                                                                           
```CSS
section { 
 width: 400px;
 display: flex; 
 flex-direction: row; 
 flex-wrap: wrap; 
}

section > div{
 flex-basis: 200px;
}
```

💻 [Code](https://github.com/Neha/css-flex-box/tree/master/basis)                

## 👍 Order

There are a few cases where we might need to change the order of the elements to appear different visually and in DOM. In such cases, we have `order` from flex that helps the developer to change the order of the elements - `visually`.

1) Order can accept the negative value. If given -1 then the element will stick to the first position.

2) If 2 elements have the same value then the deal-breaker would be their order in the DOM.

3) On row-reverse, the order in the DOM will be respected

```HTML
<section>
    <div class="one">1</div>
    <div class="two">2</div>
    <div class="three">3</div>
    <div class="four">4</div>
    <div class="five">5</div>
</section>
```

```CSS
.one {
  order: 5;
}

.three {
  order: 1;
}
```
![order](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/111clz1rhwi44gx39zo3.png)

💻 [Code](https://github.com/Neha/css-flex-box/tree/master/order)

>> Accessibility and order: As we are changing `order` visually using CSS and not through DOM, we need to take care of the accessibility - tabbing order, focusing order, etc.

## 👍 gap

To give the space between the row and column we use `gap`. The issue with margins is it doesn't collapsed the `top/bottom margin` and we end up with the extra space. However, `gap` has no such issue. 

>> When you are working with `flex` use `gap`

![gap](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u3xkbjhi4u24yfpcbniy.png)

```CSS
section { 
 width: 400px;
 display: flex; 
 flex-direction: row; 
 flex-wrap: wrap; 
 gap:10px;
}

section > div{
 width: 200px;
}
```

💻 [Code](https://github.com/Neha/css-flex-box/tree/master/gap)

## 👍 alignment

Now, we know that `flex` has a container (parent) and items (children). To align the items and container `flex` provide us the following property:

1) justify-content
2) align-items 
3) align-content

>> if you know grids, then you will notice that flex doesn't have the `justify-items` property. A good read from [stack overflow](https://stackoverflow.com/questions/32551291/in-css-flexbox-why-are-there-no-justify-items-and-justify-self-properties) on WHY?

In flex we align the items and have space between them across 'main' and 'cross' axis.

> Remember `main-axis` is dependent on the `flex-direction` and `cross-axis` is always perpendicular to the `main-axis`.

### 👍 justify-content

`Justify-content` defines how the browser distributes space *between* and *around* content items across `main-axis`.

> Remember `main-axis` is dependent on the `flex-direction`

```HTML
<section>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
</section>
```

```CSS
section { 
 width: 800px;
 display: flex; 
 flex-direction: row; 
 flex-wrap: wrap; 
 justify-content: space-between;
}

section > div{
 width: 200px;
}
```

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f28uklqsnsu5tky1kjz6.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2jz0t36xal92794ob9u6.png)

| property  |  values | 
|---|---|
| justify-content | start, center, end, flex-end, flex-start, space-between, space-around, space-evenly, stretch|

### 👍 align-items

It will align the items to the `cross-axis`

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pavtxqj1dg6cxiq97i3f.png)

```HTML
<section>
   <div>1</div>
   <div>2</div>
   <div>3</div>
   <div>4</div>
   <div>5</div>
</section>
```

```CSS
section { 
 width: 800px;
 display: flex; 
 flex-direction: row; 
 flex-wrap: wrap; 
 align-items: center;
}

section > div{
 width: 200px;
}
```

| property  |  values | 
|---|---|
| align-items | stretch , flex-start ,flex-end , center , baseline, start, end, ...  |

### 👍 align-content

It will align the content across the `main-axis`. It doesn't work with a single line. It needs to have multiple lines. The height of the flex container should be more than the height required to display items.

In the developer language, `align-content` distribute the available space between the rows and columns.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6e3kihz8g2pxcw2dok0d.png)

```HTML
<section>
   <div>1</div>
   <div>2</div>
   <div>3</div>
   <div>4</div>
   <div>5</div>
   <div>6</div>
   <div>7</div>
   <div>8</div>
   <div>9</div>
   <div>10</div>
</section>
```

```CSS
section { 
 width: 800px;
 display: flex; 
 flex-direction: row; 
 flex-wrap: wrap; 
 justify-content:wrap;
}

section > div{
 width: 200px;
}
```

| property  |  values | 
|---|---|
| align-content | flex-start , flex-end , center , space-between , space-around , space-evenly, stretch... |



## 💫 Shorthand 

There are a few shorthands we should be aware of:

1) flex-grow + flex-shrink + flex-basis

`flex: flex-grow flex-shrink flex-basis`

`flex: 1` : unit-less value means `flex-grow` & rest is 0

`flex: 2em` : declaring `flex-basis` and rest is 0

`flex: 1 2` : unit less value means `flex-grow` and `flex-shrink`

2) flex-direction + flex-wrap

`flex-flow: flex-direction flex-wrap`

`flex-flow: column no-wrap`


## ⚡️ CSS Grids vs flex

| property  |  grids | flex |
|---|---|---|
| type  | 2D  |  1D |    
| rows/columns  | Can have both  |  Can have either row or column | 
| layouts  | Can create complex layout  |  Not a good choice to create complex layout |    
| lines  | It has grid-lines |  Doesn't have flex-lines |
| Justify-content  | Has |  Doesn't have |    
| align/justify  | is not dependent on the rows/columns choice |  dependent on the flex-direction |    


## Before we say bye do check [Caniuse.com](https://caniuse.com/) for the support of the flex and its properties at different.