CSS Flexbox part 2
Tags: beginners, css
Published: 2019-11-22 22:46:09

---
title: CSS Flexbox part 2
published: true
description: A beginners introduction to CSS Flexbox
tags: beginners, css
series: FrontEnd Development Zero to Hero
---
This post is the second part of [_CSS Flexbox part 1_](https://dev.to/ziizium/css-flexbox-part-1-48f9). If you've not read the post I'll encourage you read it before proceeding with this post.


{% link https://dev.to/ziizium/css-flexbox-part-1-48f9 %}

__All code snippets remain the same unless otherwise stated.__

<hr>

###__FLEX PROPERTIES: FLEXIBILITY__
Based on your design you might want your _flex items_ to shrink or grow in size depending on the size of the flex container. There are flexbox properties designed for this specific purpose they are:

* `flex-grow`
* `flex-shrink`
* `flex-basis`
* `flex`

###__`flex-grow`__
The name of this property says it all. Let's see what the [specification]( https://www.w3.org/TR/css-flexbox-1/#valdef-flex-flex-grow) has to say:

> the flex grow factor, which determines how much the flex item will grow relative to the rest of the flex items in the flex container.

This means this property defines the ability for a flex item to grow if necessary. "Grow" in the sense that if one flex item has a `flex-grow` value greater than the `flex-grow` value of the remaining flex items in the container , this value will determine how much space it will take.  When omitted, it is set to `1`.

Now you might ask : What is the relationship between flexbox and space?

Well, space distribution is one of the features of _Flexbox Layout_ and the [specification]( https://www.w3.org/TR/css-flexbox-1/#overview) sums it up nicely (emphasis mine):

> Flex layout is superficially similar to block layout. __It lacks many of the more complex text- or document-centric properties__ that can be used in block layout, such as floats and columns. __In return it gains simple and powerful tools for distributing space and aligning content in ways that web apps and complex web pages often need__. 

For example if we give the paragraph (`p`) a `flex-grow` value of `2`, this means it will take up twice the space of the unordered list (`ul`).

Let's see some code.

If you have any flex property in your `p` CSS rule, kindly _delete_ them and add the following:

```css
p {
  /* All other properties remain the same */
  
  flex-grow: 2;
}
```

Save and refresh your browser and make sure your _Developer Tools_ is closed.

![Text with red and magenta colored borders](https://thepracticaldev.s3.amazonaws.com/i/ia52nq963ag75xjouac0.png)

It is evident from the image above the paragraph now takes much space than the unordered list.

Access the _Developer Tools_ and observe the _Flexibility_  and _Final Size_ values.

![Firefox Developer Tools](https://thepracticaldev.s3.amazonaws.com/i/jv244ka6jmcuj2od1v83.PNG)

_Resize_ the _Developer Tools_ or browser window and keep track of these values.

![Firefox Developer Tools](https://thepracticaldev.s3.amazonaws.com/i/eft46l3tkznghb3tt2vm.PNG)

When you get to a certain point the _Flexibility_ in the _Developer Tools_ will change to `flex-shrink`.

![Firefox Developer Tools](https://thepracticaldev.s3.amazonaws.com/i/d1w4rw11apvx3zl9ta2w.PNG)

Let's talk about that.

###__`flex-shrink`__
This defines the ability for a flex item to shrink if necessary. The [specification](https://www.w3.org/TR/css-flexbox-1/#valdef-flex-flex-shrink) states (emphasis mine):

> flex shrink factor, which determines how much the flex item will shrink relative to the rest of the flex items in the flex container __when negative free space is distributed__

The emphasized part means we wont see the effect of the flex shrink until the size of the flex container is negative.

__Delete__ any flex property you might have in the `p` CSS rule and add the following:

```css
p {
  /* All other properties remain the same */
  
  flex-shrink: 2;
}
```

Save and refresh your browser. You might not notice any changes until you resize you browser window or _Developer Tools_.

![Firefox Developer Tools](https://thepracticaldev.s3.amazonaws.com/i/y528wghi8alli42oqz0e.PNG)

###__`flex-basis`__

This is is the initial size of the flex item before space distribution. It can take the following values:
* `auto` &#x2014; The width or height property of the element is used
* `content` &#x2014; This will size the element based on its content
* `width` &#x2014; This is the same as the normal width and height of the element

###__`flex`__

This is the shorthand property for `flex-grow`, `flex-shrink` and `flex-basis`. Based on the [specification]( https://www.w3.org/TR/css-flexbox-1/#flex-property) the `flex-shrink` and `flex-basis` are optional. The default value is `0, 1, auto`.

The syntax is:

```css
.flex-item {
  /*
   * 1. flex-grow
   * 2. flex-shrink
   * 3. flex-basis
  */

        /*1*/ /*2/ /*3*/
  flex: 0     1    2em;
}
```

It is recommended to always use the `flex`  shorthand rather than its longhand properties directly i.e declaring `flex-grow`,`flex-shrink` and `flex-basis` separately in your code.

The table below list some values that can be supplied to the `flex` property and the corresponding values for `flex-grow`,`flex-shrink` and `flex-basis`  that will be computed by the browser.


| flex values        | equivalent
| ------------- |:-------------:|
| `flex: initial`      | `flex: 0 1 auto` | 
| `flex: auto`      | `flex: 1 1 auto`      | 
| `flex: none` | `flex: 0 0 auto`      |

###__FLEX PROPERTIES: ALIGNMENT__
The properties used for alignment allow item(s) to be placed in a desired location in the flex container. These properties are:

* `justify-content`
* `align-items` and `align-self`
* `align-content`

###__`justify-content`__
This property is used to align flex items along the main axis of the current line of the flex container. The main axis can be from left to right or from top to bottom depending on the `flex-diretion` property value. It accepts the following value:

* `flex-start` &#x2014; This is the default behavior and items are packed at the beginning of the flex container
* `flex-end` &#x2014; Flex items are packed toward the end of the flex-direction
* `center` &#x2014; The name says its all and the flex items will aligned to the center 
* `space-between` &#x2014; Flex items are distributed in the line. First flex item will be on the start line, and the last item will be on the end line
* `space-around` &#x2014; Flex items are distributed in the line, with half-size spaces on either end. "Half-size" in this sense means that the space at the beginning and the end of the line will be half of each space between the flex items

Let's code.

Each of these values will be applied to the `.parent` CSS rule because it is the flex container. First lets apply `center`:

```css
.parent {
 /* All other property remain the same */
 
 justify-content: center;
}
```

The result in the browser:

![Text with red and magenta colored borders](https://thepracticaldev.s3.amazonaws.com/i/ky7phttdo4fkta1bamo6.png)

Now, lets separate the paragraph text and the unordered list. Update the property value and don't forget to save your file before refreshing your browser.

```css
.parent {
 /* All other property remain the same */
 
 justify-content: space-between;
}
```

The result in the browser:

![Text with red and magenta colored borders](https://thepracticaldev.s3.amazonaws.com/i/12y4jd3r8txhd0mz7m9q.png)

I'll leave you to have fun with `space-around` and `flex-end`.

###__`align-items` and `align-self`__
This property is similar to `justify-content` but in the perpendicular direction. i.e the _cross axis_. `align-items` will apply to all flex items and `align-self` can be used on a single flex item overriding the value of `align-items` set on the item.

The following value can be used:

* ` auto` &#x2014; This is the default value of `align-self`
* `flex-start` &#x2014;  The item(s) will be at the beginning of the cross axis
* `flex-end` &#x2014; This is analogous to `flex-start`
* `center` &#x2014; Item(s) will be at the center of the cross axis
* `baseline` &#x2014; The flex items on the line are aligned such that their baselines align.
* `stretch` &#x2014; The item will stretch to fill the container 
Now, some code.

First, we'll give the `.parent` some padding so that we can see the effect of the values.

```css
.parent {
  /* All other property remain the same */
  
  padding: 1.2em; /* Add this */
}
```

Make sure there is no `justify-content` property then add the following to the `.parent` CSS rule:

```css
.parent {
  /* All other property remain the same */
  
  align-items: center; /* Add this */
}
```

The result in the browser:

![Text with red and magenta colored borders](https://thepracticaldev.s3.amazonaws.com/i/dwpp1n9ccxr5dsw3iefy.png)

Update the value and save your file.

```css
.parent {
  /* All other property remain the same */
  
  align-items: flex-end; /* Add this */
}
```

The result in the browser shows the paragraph text moved down. Don't forget the space below the paragraph is the padding of `.parent`.

![Text with red and magenta colored borders](https://thepracticaldev.s3.amazonaws.com/i/plurved6g1pnq5s1zwno.png)

I'll leave you to have fun with the remaining values.

###__`align-content`__
This property __pack__  flex items along the cross axis __when there is extra space__  similar to how `justify-content` aligns flex items within the main-axis. 

The following values can be used and we've explained them before under `justify-content` but here they apply to the cross axis.
* `flex-start`
* `flex-end`
* `center`
* `space-between`
* `space-around`
* `stretch`

The [specification]( https://www.w3.org/TR/css-flexbox-1/#propdef-align-content) states (emphasis mine):

>  __Only multi-line flex containers ever have free space in the cross-axis__ for lines to be aligned in, because in a single-line flex container the sole line automatically stretches to fill the space.

This means for us to see this property in action we have to make the flex containers span multiple lines.

Armed with this knowledge, we will have to update our HTML and CSS.

_Please read the comments in the CSS code_.

```html
<div class="parent">
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
</div>
```
```css
.parent {
  outline: 1px solid blue;
  background-color: #f9f9fa;
  width: 300px;            /* The parent width */
  height: 500px;           /* The height for the space in the cross axis */
  margin: 0 auto;          /* This will position the box in the center of the page */
  padding: 0.5em;          /* Just some internal spacing */
  display: flex;           /* We definitely need the flex container */
  flex-flow: row wrap;     /* This will let the items wrap multiple lines if necessary */
}

.box {
  width: 100px;              /* The width of the box */
  height: 100px;             /* The height of the box */
  margin-right: 0.5em;       /* Some outer spacing to the right of the box */
  margin-bottom: 0.5em;      /* Some outer spacing to the bottom part of the box */
  background-color: tomato;  /* Color! */
}
```

Save your files and refresh your browser. Your output should be similar to the image below.

![Orange boxes](https://thepracticaldev.s3.amazonaws.com/i/wtvv9tkfz37crn95dzhq.png)

Now let's have some fun!

Add the following code to the `.parent` CSS rule

```css
.parent {
  /* All properties remain the same */
  
  align-content: flex-start; /* Add this */
}
```

Save and refresh and BAM! all the flex item move up to the beginning of the cross axis.

![Orange boxes](https://thepracticaldev.s3.amazonaws.com/i/3iegvqm9tg0mr90dlslt.png)

Change the value:

```css
.parent {
  /* All properties remain the same */
  
  align-content: flex-end; /* A new value */
}
```

The result in the browser:

![Orange boxes](https://thepracticaldev.s3.amazonaws.com/i/cas704efxkxyy5big0d3.png)

How about some vertical spacing between the boxes?

```css
.parent {
  /* All properties remain the same */
  
  align-content: space-between; /* A new value */
}
```

The result in the browser:

![Orange boxes](https://thepracticaldev.s3.amazonaws.com/i/2zcy5ku387f9kgn2ls80.png)

The subsequent images are for the remaining values `center` and `space-around`.

![Orange Boxes](https://thepracticaldev.s3.amazonaws.com/i/9wbtiitdqgq20lh42x14.png)
<figcaption>align-content: center;</figcaption>

![Orange Boxes](https://thepracticaldev.s3.amazonaws.com/i/x4ioh0crjox7fc4sblqn.png)
<figcaption>align-content: space-around;</figcaption>

`stretch` is identical to `flex-start` and you can truly see it in action if the leftover free-space is negative. I'll leave that to you.

We've come long way in this two part post but guess what? I left out some stuff. Here are few of them:

* [Aligning with auto-margins](https://www.w3.org/TR/css-flexbox-1/#auto-margins)
* [Flex Item Z-Ordering](https://www.w3.org/TR/css-flexbox-1/#painting)
* [Reordering and Accessibility](https://www.w3.org/TR/css-flexbox-1/#order-accessibility)
* [Flex Item Margins and Paddings](https://www.w3.org/TR/css-flexbox-1/#item-margins)

That's it for now. Up next _CSS Grid_.