CSS Flexbox part 2

Habdul Hazeez - Nov 22 '19 - - Dev Community

This post is the second part of CSS Flexbox part 1. If you've not read the post I'll encourage you read it before proceeding with this post.

All code snippets remain the same unless otherwise stated.


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 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 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:

p {
  /* All other properties remain the same */

  flex-grow: 2;
}
Enter fullscreen mode Exit fullscreen mode

Save and refresh your browser and make sure your Developer Tools is closed.

Text with red and magenta colored borders

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

Resize the Developer Tools or browser window and keep track of these values.

Firefox Developer Tools

When you get to a certain point the Flexibility in the Developer Tools will change to flex-shrink.

Firefox Developer Tools

Let's talk about that.

flex-shrink

This defines the ability for a flex item to shrink if necessary. The specification 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:

p {
  /* All other properties remain the same */

  flex-shrink: 2;
}
Enter fullscreen mode Exit fullscreen mode

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

Firefox Developer Tools

flex-basis

This is is the initial size of the flex item before space distribution. It can take the following values:

  • auto — The width or height property of the element is used
  • content — This will size the element based on its content
  • width — 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 the flex-shrink and flex-basis are optional. The default value is 0, 1, auto.

The syntax is:

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

        /*1*/ /*2/ /*3*/
  flex: 0     1    2em;
}
Enter fullscreen mode Exit fullscreen mode

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 — This is the default behavior and items are packed at the beginning of the flex container
  • flex-end — Flex items are packed toward the end of the flex-direction
  • center — The name says its all and the flex items will aligned to the center
  • space-between — 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 — 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:

.parent {
 /* All other property remain the same */

 justify-content: center;
}
Enter fullscreen mode Exit fullscreen mode

The result in the browser:

Text with red and magenta colored borders

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.

.parent {
 /* All other property remain the same */

 justify-content: space-between;
}
Enter fullscreen mode Exit fullscreen mode

The result in the browser:

Text with red and magenta colored borders

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 — This is the default value of align-self
  • flex-start — The item(s) will be at the beginning of the cross axis
  • flex-end — This is analogous to flex-start
  • center — Item(s) will be at the center of the cross axis
  • baseline — The flex items on the line are aligned such that their baselines align.
  • stretch — 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.

.parent {
  /* All other property remain the same */

  padding: 1.2em; /* Add this */
}
Enter fullscreen mode Exit fullscreen mode

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

.parent {
  /* All other property remain the same */

  align-items: center; /* Add this */
}
Enter fullscreen mode Exit fullscreen mode

The result in the browser:

Text with red and magenta colored borders

Update the value and save your file.

.parent {
  /* All other property remain the same */

  align-items: flex-end; /* Add this */
}
Enter fullscreen mode Exit fullscreen mode

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

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 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.

<div class="parent">
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
</div>
Enter fullscreen mode Exit fullscreen mode
.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! */
}
Enter fullscreen mode Exit fullscreen mode

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

Orange boxes

Now let's have some fun!

Add the following code to the .parent CSS rule

.parent {
  /* All properties remain the same */

  align-content: flex-start; /* Add this */
}
Enter fullscreen mode Exit fullscreen mode

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

Orange boxes

Change the value:

.parent {
  /* All properties remain the same */

  align-content: flex-end; /* A new value */
}
Enter fullscreen mode Exit fullscreen mode

The result in the browser:

Orange boxes

How about some vertical spacing between the boxes?

.parent {
  /* All properties remain the same */

  align-content: space-between; /* A new value */
}
Enter fullscreen mode Exit fullscreen mode

The result in the browser:

Orange boxes

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

Orange Boxes

align-content: center;

Orange Boxes

align-content: space-around;

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:

That's it for now. Up next CSS Grid.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .