Flexbox Basics
Tags: flexbox, beginners, css, cssflexbox
Published: 2022-07-26 16:48:00

Today I'm back with the second building block in CSS: Flexbox! Handily created in 2009 to facilitate dynamic layouts.

I was first introduced to these concepts by my [General Assembly](https://generalassemb.ly/education/software-engineering-immersive/london?ga_campaign=immersive-remote&ga_variation=sei-tile) Software Engineering Immersive a few weeks back. Since then, I've completed a few labs and projects with them. 👩‍💻

But what was most impactful was having played and replayed [Flexbox Froggy](https://flexboxfroggy.com/) & [Flexbox Zombies](https://mastery.games/flexboxzombies/) many times. Each time I replayed these games, I discovered a new insight I previously overlooked, and the concepts were further cemented. 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qet2reeyu8jmss2427wi.png)

I know these games look silly, but truthfully, they are game (no pun intended) changers to your learning experience 🪄

# Part 1 Setting up Flexbox 
In order to begin using the magic of Flexbox, we must set up the relevant containers by adding extra `<div>`s in our HTML. 

In our CSS file, we select the `<div>` by the class we've assigned to it, and apply `display: flex`. 

Then, we can begin using the following properties to target the _elements_ nested directly within the _container_... 

# Part 2 Alignment Properties
_Location Applied_
= These properties & their corresponding values are applied at the container-level 
_Purpose_
= They will affect the spacing & positioning of elements w/in the container 

## 2.1 `flex-direction`
### Purpose
= Defines direction elements are placed w/in container

### Default Value
= `row` (Much like the effect of `display: inline`)
--> Elements nested directly w/ container: Populated along x-axis

### Values
1. `row`
= (Refer to description above)
2. `row-reverse`
= Elements populated in reverse order of text direction
3. `column`
= Elements populated in order along y-axis 
4. `column-reverse`
= Elements populated in reverse order along y-axis 

## 2.2 `justify-content`
### Purpose 
--> `row`
= Spacing along x-axis 
--> `column`
= Spacing along y-axis

### Default Value 
= `flex-start`

### Values
1. `flex-start`
--> If `flex-direction: row`
= Elements placed flush against _left_ of container
--> If `flex-direction: column`
= Elements placed flush against _top_ of container

2. `flex-end`
--> If `flex-direction: row`
= Elements placed flush against _right_ of container
--> If `flex-direction: column`
= Elements placed flush against _bottom_ of container

3. `center`
--> If `flex-direction: row`
= Elements packed flush together & placed in middle of container _y-axis_
--> If `flex-direction: column`
= Elements packed flush together & placed in middle of container _x-axis_

4. `space-between`
--> If `flex-direction: row`
= Divides up remaining container _x-axis_ space, adds equal amount _between_ elements
--> If `flex-direction: column`
= Divides up remaining container _y-axis_ space, adds equal amount _between_ elements

5. `space-around`
--> If `flex-direction: row`
= Divides up remaining container _x-axis_ space, adds equal amount _around_ both sides of each element
--> If `flex-direction: column`
= Divides up remaining container _y-axis_ space, adds equal amount _around_ both sides of each element

## 2.3 `align-items`
### Purpose
--> `row` = Spacing along y-axis 
--> `column`= Spacing along x-axis

### Default Value 
= `flex-start`

### Values
1. `flex-start`
--> If `flex-direction: row`
= Elements flush to _top_ of container
--> If `flex-direction: column`
= Elements flush to _left_ of container 

2. `baseline`
1/ Targets _tallest_ element
2/ Aligns _tallest_ element's top-most/left-most (row/column) edge with the top-most/left-most (row/column) edge of container 
3/ Aligns rest of elements' baseline w/ baseline of _tallest_ element

##### What is the baseline?
= Where letters 'sit'
--> Descenders of letters extends below baseline

##### Use Case
= Content size varies among elements
--> If content size is the same, baseline: Same effect as `flex-start`

3. `flex-end`
--> `row`
= Align Elements flush to _right_ of container
--> `column`
= Align Elements flush to _bottom_ of container

4. `center`
--> `row`
= Elements packed flush together & placed in middle of container _x-axis_
--> `column`
= Elements packed flush together & placed in middle of container _y-axis_

5. `stretch`
--> `row`
= Aligns top & bottom of element flush with top & bottom of container by stretching entire element
--> `column`
= Aligns left & right of element flush with left & right of container by stretching entire element

## 2.4 `order`
### Purpose 
= Swap the position of an element w/in its group of elements

### Application 
= To individual element

### Default Value 
= `0`

### Values
= Can be Positive or Negative
**Effects of Values**
1. Since Default Value for any Element: `0`
2. Element w/ Positive `order` Value
= Immediately moved to back 
3. Element w/ Negative `order` Value 
= Immediately moved to front
**Reason**
= `order` Values set to Elements --> Place the Elements in chronological order (From negative to positive values)

## 2.5 `align-self`
### Purpose
--> `row`
= Align an individual element on container's _y-axis_
--> `column`
= Align an individual element on container's _x-axis_

### Application
= To a specific element 

### Values 
= Same as `align-items

## 2.6 `flex-wrap`
### Purpose
= Create more space for Elements
--> By providing them w/ space beyond their present line
--> Allowing Elements to maintain size 

### Default Value 
= `nowrap`
--> Will shrink Elements to fit into line

### Values 
1 . `nowrap`
= Fit all elements into 1 line
--> Even if this means shrinking them 
2. `wrap`
= Add additional lines to populate elements 
3. `wrap-reverse`
= Add additional lines to populate elements
--> In reverse order 

## 2.7 `align-content`
### Purpose
= Spacing & Positioning of 'lines'/'groups' of elements 
--> Takes in & manipulates each 'line' the way `align-items` take in each 'element'

### Application
= Applied with `flex-wrap: wrap`
--> W/o `flex-wrap: wrap`, `align-content` has no effect

### Values 
1. `flex-start`
--> If `flex-direction: row`
= Lines flush to _top_ of container
--> If `flex-direction: column`
= Lines flush to _left_ of container 

2. `flex-end` 
--> If `flex-direction: row`
= Elements flush to _bottom_ of container
--> If `flex-direction: column`
= Elements flush to _right_ of container 

3. `center` 
--> `row`
= Lines packed flush together & placed in middle of container _x-axis_
--> `column`
= Lines packed flush together & placed in middle of container _y-axis_

4. `space-between`
--> If `flex-direction: row`
= Divides up remaining container _y-axis_ space, adds equal amount _between_ lines
--> If `flex-direction: column`
= Divides up remaining container _x-axis_ space, adds equal amount _between_ lines

5. `space-around`
--> If `flex-direction: row`
= Divides up remaining container _y-axis_ space, adds equal amount _around_ both sides of each line
--> If `flex-direction: column`
= Divides up remaining container _x-axis_ space, adds equal amount _around_ both sides of each line

6. `stretch`
--> `row`
= Aligns top & bottom of line flush with top & bottom of container by stretching each entire line
--> `column`
= Aligns left & right of line flush with left & right of container by stretching each entire line

### `align-content` vs `align-items`
= `align-content`: Spacing & Positioning of _lines_ of elements
= `align-items`: Spacing & Positioning of _individual_ elements 

# Part 3 Speed of Resizing Properties
## 3.1 Alignment vs Resizing Properties
= In all cases, the Flexbox is created on the container
But...
--> Alignment Properties: Applied by selecting Container in CSS
--> Resizing Properties: Applied by selecting Elements themselves in CSS

## 3.2 `flex-grow`
### Interactions w/ other properties
= Nullifies any effect of `justify-content`
--> Unless there are new lines

### Purpose 
= Enlarge Element(s) to fill ALL available space
--> Works the same for horizontal (`flex-direction: row`) & vertical (`flex-direction: column`) space

### Application 
= Directly to Elements
--> Not on Elements' container

1. Apply `flex-grow: 1` to class w/ all similar elements
2. Override growing for specific elements that do not grow 
= `flex-grow: 0`
3. Adjust ratios for specific elements growing faster
= **ie** `flex-grow: 3` 
--> Grows 3X as fast as any other element w/ `flex-grow: 1`

### Default Value
= `0`
--> Will not grow unless told to 

### Values
= Ratios
--> Set 2 elements `flex-grow: 1` = Both grow to fill available space at same rate

### Example 
--> Set 1 element to grow at 2X the speed of another element
= `flex-grow: 2`, `flex-grow: 1`
= 2X the SPEED, NOT 2X the SIZE: Both growing to fill available space 

## 3.2 `flex-shrink`
### Purpose
= React when there is not enough space for elements 

### Default Value
= `1`
--> Shrinks without explicitly setting values 

### Values 
= Ratios
--> Used to control how quickly each element shrinks (Speed)

### Application
= Elements shrink at a rate relative to each other 

1. All Elements shrinking at same speed
= Do not set `flex-shrink`: This is covered by default value 
2. Certain Elements shrinking 2X as fast
= `flex-shrink: 2`
--> Shrinking twice the SPEED, not SIZE
--> For every 1 pixel, these shrink 2 pixels each
3. Refuse to shrink
= `flex-shrink: 0`
--> Specified on individual element

### Shrinking & Growing
= Can be used in combination 
--> By Default: Applying `flex-grow` = Used w/ `flex-shrink: 1`
= Will Grow & Shrink depending on existence of extra space || lack of space 
--> If want elements to Shrink at same speed && Grow
= Only set `flex-grow`: B/c `flex-shrink` is set to `1` by Default already 

## 3.3 `flex-basis`
### Purpose
= Starting point/Ideal world (before any _growing_ or _shrinking_)
--> Enough space to fit `flex-basis` defined: Element takes on size defined by `flex-basis`
--> Not enough space to fit `flex-basis` defined: Element takes on only the amount of size _permitted_ by space

### Default Value 
= `auto`
--> Same as `width` value

### Values 
**Units of Measurement**: 
1. Pixels
2. Percentages
_Example_: `flex-basis: 50%`
= Takes up 50% of width of container

### Application
--> `flex-direction: row` 
= `flex-basis` targets the _width_
--> `flex-direction: column`
= `flex-basis` targets the _height_

##### Final `flex-basis` Contributors
1. `width`/`height`
= If `flex-basis` specified
--> `width`: Overridden & Ignored

2. `min-width`/`min-height`
= Lower Limit for `flex-basis`
**Example**: `min-width: 300px`/`min-height: 300px` && `flex-basis: 100px`
--> Final `flex-basis` = 300px (`min-width`)

**Example**: `min-width`/`min-height` > `flex-basis` set
--> Final `flex-basis` = `min-width/min-height`

3. `max-width`/`max-height`
= Upper Limit for `flex-basis`
**Example**: `flex-basis` > `max-width`/`max-height`
--> Final `flex-basis` = `max-width`/`max-height` 

##### Order of Overriding 
`min/max-width/height` > `flex-basis` > `width/height` 

### Interactions w/ Other Properties
1. `flex-basis: 0`
= Will not show the Element, unless `flex-grow` is set
--> Size set to 0 until growing begins 

2. `flex-shrink: 0`
= Does not allow Element to shrink past `flex-basis` size

3. `flex-grow` need not be specified 
= If `flex-basis` > Current `width`/`height` 
&& Element does not need to grow beyond `flex-basis` size
--> `flex-basis` can sometimes be mistaken for `flex-grow`

4. Available space does not allow for `flex-basis` size
= Element shrinks according to `flex-shrink`/default shrinking

5. Available space increases && Element has specified `flex-grow`
= Element grows _beyond_ `flex-basis` size 
**Example**: `flex-basis: 200px` && `flex-grow: 1`

# Part 4 Shorthand Properties
## 4.1 `flex-flow`
### Purpose
= Combines `flex-direction` & `flex-wrap`

### Values 
= Values of `flex-direction` & `flex-wrap`
--> Separated by a space

### Example 
`flex-flow: row wrap`
= Sets rows & wraps them into additional lines

## 4.2 `flex`
### Purpose 
= Combines 2 Settings: `flex-grow`, `flex-shrink`, & `flex-basis`

### Default Values
1. Leave off 3rd Value: `flex-basis`
= `flex-basis` set to **0px** by default 
--> (unlike how `flex-basis` is set to **`auto`** as a default without `flex` property)**

**Example**: `flex: 1 0 auto` = Grow at speed of 1, not shrink, and use `width` as `flex-basis`

2. Leave off 2nd Value: `flex-shrink`
= `flex-shrink` set to `1`
--> Same as _regular_ `flex-shrink` default

**Example**: `flex: 0 300px` = No growing && `flex-basis: 300px`

3. Leave off both 2nd & 3rd Values: `flex-shrink` & `flex-basis`
= Default: `flex-basis: 0px` && `flex-shrink: 1`

**Example**: `flex: 1;` = Only sets `flex-grow: 1`

### Values: Keyword Shortcuts
1. `flex: auto`
= `flex-grow: 1`, `flex-shrink: 1`, `flex-basis: auto`
--> Grows & Shrinks & Keeps initial size = `width`

2. `flex: none`
= `flex-grow: 0`, `flex-shrink: 0`, `flex-basis: auto`
--> No Growing & No Shrinking & Initial size = `width`

### Example
= `flex: 1 1 300px`
--> `flex:` `grow` `shrink` `basis`

### Caution
= Setting a `flex` without specifying the 3rd value
--> Sets your `flex-basis` from `auto` to `0px`

...And that's it for **CSS Flexbox**! I'll be returning here to add additional notes and use cases after further personal usage. Super excited to continue sharing my experiences with you <3

Next week, we'll be moving onto **CSS Grid** to wrap up **CSS Essentials**! 🤳

With love,
Angeline