# Adding Flexbox To Our Website ## Understanding Flexbox It allows us to change the way our elements are displayed. To use flex box we can add the `display` property with value `flex` to an element, and that element will now be turned into a **flex container**. Inside our **flex container**, we will add different elements, which are also called **flex items**. Once we add the `flex` construct we can add different properties to the parent (**flex container**) and the children (**flex items**). | Parent Properties | Children Properties | | --- | --- | | `flex-flow` | `...` | | `justify-content` | `order` | | `align-content` | `flex` | | `align-items` | `align-self` | ## Creating A **Flex Container** When you apply the `display: flex;` property to a parent element, all children inside that element will be displayed in a single row by default. We can also use `display: inline-flex`, which as the name suggests turns the parent into a flex container but itself is an inline element. ### Using `flex-direction` And `flex-wrap` `flex-direction` has the default value `row`. Changing its value to `column` would display all the items in a single column or vertically. We also have `row-reverse` and `column-reverse` values for this property which display the items in the reverse order. `flex-wrap` has the default value `nowrap`. If we change it's value to `wrap`, the overflown elements will jump to the next row. We also have also value `wrap-reverse`, which does the same as `wrap` but in the reverse order, that is the first element would jump to the next row if we reduce the width. We also have a shorthand these two properties, which is `flex-flow`, e.g. `flex-flow: row wrap;`. ### Understanding The Importance Of Main Axis And Cross Axis The **main axis** if we apply the property `flex-direction: row;`, starts from top left with direction towards right, and the **cross axxis** is top left to bottom. For `flex-direction: column;`, the **main axis** would be from top left to bottom, and the **cross axis** would be from top left to right. We have two other values for `flex-direction` property, that are `row-reverse` and `column-reverse`, which has the same axis as `row` and `column` values but have opposite directions. ### Working With `align-items` & `justify-content` With `align-items` we can align our elements along the **cross axis**. The default value for this property is `stretch`. Other values are `center`, `flex-start`, `flex-end`, `baseline` etc. To align items along the **main axis**, we use the property `justify-content`. To see the available values, go to [link](https://developer.mozilla.org/en-US/docs/Web/CSS/align-items) for `align-items`, and [link](https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content) for `justify-content`. ### What About The `align-content` The last property to look at for the **flex container** is `align-content`. It is also used to align our items along the **cross axis** but for **multiline flex containers**, so it is used to determine the spacing between multiline container and has no effect for a single line flex container. ## Flex Items We can use different properties on flex items like `order`, `flex` (shorthand for `flex-grow`, `flex-shrink` and `flex-basis`) and `align-self`, to have impact on a single item. ### Understanding The `order` Property The `order` property changes the order of an item inside the flex container, the default value is `0`. We can change its value to `1` or `-1` to move the flex item to end or front of other items, based on the main axis. Or we can also use other numbers to order the items accordingly. ### Working With `align-self` Like the flex container property `align-items`, we use `align-self` also to position the element in **cross axis**, but instead of all the items it is used to position a single flex item. We can use the same `flex-start`, `flex-end`, `center` etc as values. ### Understanding The `flex-grow` The `flex-grow` property also has an initial value of `0`. By applying `flex-grow: 1;` to a flex item, the element will fill the available space. If we add `flex-grow: 4;` to another flex item, then the available width will be divided into 5 parts, 1/5th for the item with `flex-grow: 1;`, and 4/5th for the item with `flex-grow: 4;` applied. If a flex item with `flex-grow: 1;` moves to a new line, it'll take the whole available space because that line won't have any other flex item to share the availabe space. ### Applying `flex-shrink` It defines the behavior as we decrease the `width`. By default decreasing the width would make flex items to shrink to a point where the items content requires the width. The default value for `flex-shrink` is `1`. If you change it to `0`, then the flex item won't shrink below it's defined `width`. We can also control the ratio by which the items shrink relatively, e.g. applying `flex-shrink: 1;` to an item and `flex-shrink: 4;` to another item will make this item shrink 4 times more than the first one. ### Comparing `flex-basis` vs `width` & `height` `flex-basis` defines the size of an element depending on the **main axis**. It is used to override the `width` or `height` properties depending on the main axis. It has the default value of `auto`. For example, adding `flex-basis: 300px;` to a flex item with main axis set as `row`, it'll override the `width` property. And likewise for an item with main axis from top to bottom it'll override the `height`.