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;
}
Save and refresh your browser and make sure your Developer Tools is closed.
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.
Resize the Developer Tools or browser window and keep track of these values.
When you get to a certain point the Flexibility in the Developer Tools will change to flex-shrink
.
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;
}
Save and refresh your browser. You might not notice any changes until you resize you browser window or 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;
}
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
andalign-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;
}
The result in the browser:
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;
}
The result in the browser:
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 ofalign-self
-
flex-start
— The item(s) will be at the beginning of the cross axis -
flex-end
— This is analogous toflex-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 */
}
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 */
}
The result in the browser:
Update the value and save your file.
.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
.
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>
.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.
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 */
}
Save and refresh and BAM! all the flex item move up to the beginning of the cross axis.
Change the value:
.parent {
/* All properties remain the same */
align-content: flex-end; /* A new value */
}
The result in the browser:
How about some vertical spacing between the boxes?
.parent {
/* All properties remain the same */
align-content: space-between; /* A new value */
}
The result in the browser:
The subsequent images are for the remaining values center
and 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:
- Aligning with auto-margins
- Flex Item Z-Ordering
- Reordering and Accessibility
- Flex Item Margins and Paddings
That's it for now. Up next CSS Grid.