A Complete Guide to Flexbox Layout
Published: 2023-03-08 06:53:36

The Flexbox Layout, also referred to as the flexible box layout, is an incredibly versatile approach to positioning, sizing, and directing items within a container. As the name suggests, it offers a flexible way to arrange elements in a layout that can easily adapt to different screen sizes and resolutions.

It is important to note that, unlike the Grid Layout, which is a two-dimensional layout, the Flexbox Layout focuses on one-dimensional layouts. This means that it can control the layout either in a row or column at a time, but not both simultaneously. However, with its ease of use and powerful capabilities, it is a highly valuable tool in web design.

Rest assured, we will delve further into this topic and explore the many benefits and usages of Flexbox Layout in the upcoming discussion.

## Basic Concept
Here is the graph describing the terms of Flexbox layout from [MDN](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox#the_flex_model). 

![Flexbox Concept](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/70mn001xq2a5w2lysvhy.png)

Let's explain the terms one by one:
1. **Flex Container**: You should use `display: flex` on the container element to declare that the container element will use Flexbox layout.
2. **Flex Items**: Any **direct children** of the Flex container will become the flex items.
3. **Main Axis**: Main axis is dependent on the direction of flex, by default it is horizontal.
4. **Cross Axis**: Cross axis is dependent on the direction of flex, by default it is vertical.
5. **Main Start/End, Cross Start/End**: They are simply the start or end of the main or cross axis.

## Related Properties
Here are almost all the related properties to the flexbox layout, we will explain how they work later.
1. **Flex container related properties**: `flex-direction`, `flex-wrap`, `flex-flow`, `justify-content`, `align-content`, `align-items`, `place-content`, `place-items`, `column-gap`, `row-gap`, `gap`
2. **Flex items related properties**: `flex`, `flex-basis`, `flex-grow`, `flex-shrink`, `order`, `align-self`

## A Quick Example
Here is a quick example of how we may use some of the properties. You can click the *index.css* to say how we use those properties.
<iframe src="https://codesandbox.io/embed/beautiful-moore-brinh1?fontsize=14&hidenavigation=1&theme=dark"
     style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;"
     title="beautiful-moore-brinh1"
     allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking"
     sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
   ></iframe>

Hope the example may give a brief idea about how flexbox works. And now let's talk about how each property works and may affect the layout in detail.

## Declare Flexbox Layout
There are two options to declare an element as the flexbox layout. The one we always use is `display: flex` which asks an element (container) to use the flexbox layout in which the element (container) itself is considered a block element. Another one is `display: inline-flex` which is just similar to the first one but the element (container) itself is the inline block.

Thus, only two ways to declare flexbox layout you should remember: `display: flex` and `display: inline-flex`.

## Flexbox Direction
By default, `display: flex` will make all the container's direct children lay along the horizontal line. But, you can also make children lay vertically by explicitly applying `flex-direction: column`. Barring aligning children horizontally or vertically, you can also reverse the children's order by applying `flex-direction: row-reverse` or `flex-direction: column-reverse`.

## Wrap
By default, the children of flex container will condense as more children are pushed. When the width of all children exceed the width of the container, the content will overflow. Usually, at this time, you will want to break the lines and put overflowed children to the next line. Thus, `flex-wrap: wrap` which will be putted on container can help you break the overflowed children to the next line. And one thing worthy to be noted is that you can almost consider each line as a flex container.

## Alignment 
Within Flexbox layout, you can align children along main axis or cross axis, align a certain specific item, or align multiple axis lines. Let's dicusse them one by one in detail.

### Main Axis Items Alignment
> `justify-content` property defines how the browser distributes space between and around content items along the [main-axis](https://developer.mozilla.org/en-US/docs/Glossary/Main_Axis) of a flex container.

We can use `justify-content` property to align direct children of the container along **main axis**. There are several values we can use for this property to align the content:
1. `center`: children will be packed and aligned in the **center** along the main axis.
2. `flex-start` and `flex-end`:  children will be packed and aligned starting from the start or end of the main axis.
4. `space-betweeen`: spaces between children will be distributed evenly while the first item is at the edge of the start of the main axis and the last item at the edge of the end of the main axis.
5. `space-around`: similar to `space-between` but the space between the edge of the start and the first item and between the edge of the end and the last item is half space of the space between each item.
6. `space-evenly`: similar to `space-around` but all the space including the space between items and edges and between items and items are the same.

### Cross Axis Items Alignment
We can use `align-items` property to align the direct children of the container along the **cross-axis**. There are several values we can use for this property to align the content:
1.  `stretch`: This is the default value. Direct children of the container will be stretched to fit the container’s cross-axis size.
2.  `center`: Direct children of the container will be aligned at the center along the cross-axis.
3.  `flex-start`: Direct children of the container will be aligned at the start of the cross-axis.
4.  `flex-end`: Direct children of the container will be aligned at the end of the cross-axis.
5.  `baseline`: Direct children of the container will be aligned at the baseline of the cross-axis, in which baseline means the first text line position.

### Item's Self Alignment
We can use `align-self` property on a certain direct child of the container to align that specific child’s position along cross-axis. The values of this property are almost the same as the values of `align-items` property with the difference that the `align-self` only applies to a certain direct child.

### Align Multiple Main Axis
When you apply `flex-wrap: wrap` on the container, there might be multiple lines. As we mentioned that you can consider each line as a flexbox container, when we want to align how these lines are aligned along the cross-axis, we can use `align-content`. The values of `align-content` are almost the same as `justify-content` but `align-content` apply to how lines are aligned along the cross-axis.

## Item Size
There are three properties associated with direct child size:  
1. `flex-basis`: initial item size  
2. `flex-grow`: how to handle the growth of the direct child size  
3. `flex-shrink`: opposite to `flex-grow`, how to handle the shrinkness of the direct child size

### Initial Size
Apply `flex-basis` on a certain direct child to set its initial size and there are several values we can use:
1. `max-content`, `min-content`, `content`: size will be determined by the content of the item
2. `<'width'>`: set specific size, like `10em`, `100px`
3. `auto`: if item has width or height property, the size is determined by its width or height, or it will fallback to `content` value

### Growness
Apply `flex-grow` on a certain direct child to control how the item is grown. 0 is not to grow.

### Shrinkness
Apply `flex-shrink` on a certain direct child to control how the item is shrunk. 0 is not to shrink.

## Item Order
We can use `order` property to change the order of a certain direct child of the container. The value of the `order` property is basically a number, the smaller the more forward, and the bigger the more latter.

## Gap
For the gap, we have three associated properties, `gap`, `row-gap`, and `column-gap`. The `gap` is the shorthand for `row-gap` and `column-gap`. 

## References
1. [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox)
2. [CSS Flexible Box Layout](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout)