📓2.1: Flexbox Layouts
Table of Contents
New Unit! Use a GitHub Template for class notes:
- Go to the public template repository for our class: BWL-CS HTML/CSS/JS Template
- Click the button above the list of files then select
Create a new repository
- Specify the repository name:
CS1-Unit-2-Notes-Flexbox
- Click
Now you have your own personal copy of this starter code that you can always access under the
Your repositories
section of GitHub! - Now on your repository, click and select the
Codespaces
tab - Click
Create Codespace on main
and wait for the environment to load, then you’re ready to code! - 📝 Take notes in this Codespace during class, coding along with the instructor.
Flexbox Layouts
As you’ll learn, there are many ways to move elements around on a web page. New methods have been developed over the years and older things have fallen out of style. Flexbox was not always available in CSS - its debut was revolutionary. Learn more about the history of flexbox.
Many resources put it near the end of their curriculum because it is somewhat new as a technology. But at this point, it has become the default way of positioning elements for many developers. Flexbox will be one of the most used tools in your toolbox, so why not learn it first?
- You will learn how to position elements using flexbox.
- You will learn about
flex containers
andflex items
. - You will learn how to create useful components and layouts that go beyond just stacking and centering items.
Let’s flex!
Flexbox is a way to arrange items into rows or columns. These items will flex (i.e. grow or shrink) based on some rules that you can define. Here are some examples of what you can control in flexible containers:
We’ve embedded a lot of interactive examples in this lesson. Take your time to experiment with them as you go to cement the concepts in your mind!
See the Pen first flex example by TheOdinProject (@TheOdinProjectExamples) on CodePen.
All 3 divs should be arranged horizontally. If you resize the results frame with the “1x”, “.5x” and “.25x” buttons you’ll also see that the divs will “flex”. They will fill the available area and will each have equal width.
If you add another div
to the HTML, inside of <div class="flex-container">
, it will show up alongside the others, and everything will flex to fit within the available area.
Flex Containers and Flex Items
As you’ve seen, flexbox is not just a single CSS property but a whole toolbox of properties that you can use to put things where you need them. Some of these properties belong on the flex container, while some go on the flex items. This is an important concept!
A flex container is any element that has display: flex
on it. A flex item is any element that lives directly inside of a flex container.
Somewhat confusingly, any element can be both a flex container and a flex item. Said another way, you can also put display: flex
on a flex item and then use flexbox to arrange its children.
Creating and nesting multiple flex containers and items is the primary way we will be building up complex layouts. The following image was achieved using only flexbox to arrange, size, and place the various elements. Flexbox is a very powerful tool.
Growing & Shrinking Items
The flex shorthand
The flex
declaration is actually a shorthand for 3 properties that you can set on a flex item. These properties affect how flex items size themselves within their container. You’ve seen some shorthand properties before, like border
, but we haven’t officially defined them yet.
Shorthand properties are CSS properties that let you set the values of multiple CSS properties simultaneously. Using a shorthand property, you can write more concise (and often more readable) stylesheets, saving time and energy.
MORE INFO: Shorthand properties on MDN
The flex
property is actually a shorthand for:
flex-grow
flex-shrink
flex-basis
Very often you see the flex shorthand defined with only one value. In that case, that value is applied to flex-grow
. So when we put flex: 1
on our divs, we were actually specifying a shorthand of flex: 1 1 0
.
div {
flex: 1;
}
In the above code,
flex: 1
equates to:flex-grow: 1
,flex-shrink: 1
,flex-basis: 0
.
Flex-grow
flex-grow
expects a single number as its value, and that number is used as the flex-item’s “growth factor”. When we applied flex: 1
to every div inside our container, we were telling every div to grow the same amount. The result of this is that every div ends up the exact same size.
If we instead add
flex: 2
to just one of the divs, then that div would grow to 2x the size of the others.
In the following example the flex
shorthand has values for flex-shrink
and flex-basis
specified with their default values.
See the Pen flex-grow example by TheOdinProject (@TheOdinProjectExamples) on CodePen.
Flex-shrink
flex-shrink
is similar to flex-grow
, but sets the “shrink factor” of a flex item. flex-shrink
only ends up being applied if the size of all flex items is larger than their parent container.
For example, if our 3 divs from above had a width declaration like:
width: 100px
, and.flex-container
was smaller than300px
, our divs would have to shrink to fit.
The default shrink factor is flex-shrink: 1
, which means all items will shrink evenly. If you do not want an item to shrink then you can specify flex-shrink: 0;
. You can also specify higher numbers to make certain items shrink at a higher rate than normal.
Here’s an example:
See the Pen flex-shrink example by TheOdinProject (@TheOdinProjectExamples) on CodePen.
Note that we’ve also changed the
flex-basis
for reasons that will be explained shortly. If you shrink your browser window, you’ll notice that.two
never gets smaller than the given width of 250px, even though theflex-grow
rule would otherwise specify that each element should be equally sized.
An important implication to notice here is that when you specify flex-grow
or flex-shrink
, flex items do not necessarily respect your given values for width
!
In the above example, all 3 divs are given a width of 250px, but when their parent is big enough, they grow to fill it. Likewise, when the parent is too small, the default behavior is for them to shrink to fit. This is not a bug, but it could be confusing behavior if you aren’t expecting it.
Flex-basis
flex-basis
sets the initial size of a flex item, so any sort of flex-grow
ing or flex-shrink
ing starts from that baseline size. The shorthand value defaults to flex-basis: 0%
.
The reason we had to change it to
auto
in theflex-shrink
example is that with the basis set to0
, those items would ignore the item’s width, and everything would shrink evenly. Usingauto
as a flex-basis tells the item to check for a width declaration (width: 250px
).
There is a difference between the default value of flex-basis
and the way the flex
shorthand defines it if no flex-basis
is given. The actual default value for flex-basis
is auto
, but when you specify flex: 1
on an element, it interprets that as flex: 1 1 0
.
If you want to only adjust an item’s flex-grow
you can do so directly, without the shorthand. Or you can be more verbose and use the full 3 value shorthand flex: 1 1 auto
, which is also equivalent to using flex: auto
.
In practice you will likely not be using complex values for flex-grow
, flex-shrink
or flex-basis
. Generally, you’re most likely to use declarations like flex: 1;
to make items grow evenly and flex-shrink: 0
to prevent shrinking of certain items.
Flexbox Axes
Let’s see how the orientation of items within a flex container can be controlled using the flex-direction
property.
- You’ll learn about the 2 “axes” of a flex container.
- You’ll learn how to change those axes to arrange your content in columns instead of rows.
The flex-direction
property
The most confusing thing about flexbox is that it can work either horizontally or vertically, and some rules change a bit depending on which direction you are working with.
The default direction for a flex container is horizontal, or row
, but you can change the direction to vertical, or column
. The direction can be specified in CSS like so:
.flex-container {
display: flex;
flex-direction: column;
}
No matter which direction you’re using, you need to think of your flex-containers as having 2 axes: the main axis and the cross axis. It is the direction of these axes that changes when the flex-direction
is changed.
In most circumstances, flex-direction: row
puts the main axis horizontal (left-to-right), and column
puts the main axis vertical (top-to-bottom).
In other words, in our very first example, we put
display: flex
on a div and it arranged its children horizontally. This is a demonstration offlex-direction: row
, the default setting.
The following example is very similar. If you uncomment the line that says flex-direction: column
, those divs will stack vertically:
See the Pen flex-direction example by TheOdinProject (@TheOdinProjectExamples) on CodePen.
NOTE: When we changed the flex-direction to
column
,flex-basis
refers toheight
instead ofwidth
! Another detail to notice: by specifyingflex: 1 1 auto
, we are telling the flex items to default to their givenheight
. We could also have fixed any height issues by putting a height on the parent.flex-container
.
Flexbox Alignment
So far everything we’ve touched with flexbox has used the rule flex: 1
on all flex items, which makes the items grow or shrink equally to fill all of the available space. Very often, however, this is not the desired effect. Flex is also very useful for arranging items that have a specific size.
- You’ll learn how to align items inside a flex container both vertically and horizontally.
The justify-content
and align-items
properties
Let’s look at an example:
See the Pen flex-alignment example by TheOdinProject (@TheOdinProjectExamples) on CodePen.
You should be able to predict what happens if you put
flex: 1
on the.item
by now. Give it a shot before we move on!
Adding flex: 1
to .item
makes each of the items grow to fill the available space, but what if we wanted them to stay the same width, but distribute themselves differently inside the container?
Remove
flex: 1
from.item
and addjustify-content: space-between
to.container
.
When to use Justify-Content
justify-content
aligns items across the main axis.
There are a few values that you can use here. For now try changing it in your code to center
, which should center the boxes along the main axis.
When to use Align-Items
To change the placement of items along the cross axis use align-items
.
In your code, try getting the boxes to the center of the container by adding align-items: center
to .container
. There are more options for this property:
Because justify-content
and align-items
are based on the main axis and cross axis of your container, their behavior changes when you change the flex-direction
of a flex container! > For example, when you change flex-direction
to column
, justify-content
aligns vertically and align-items
aligns horizontally.
The most common behavior, however, is the default, i.e. justify-content
aligns items horizontally (because the main axis defaults to horizontal), and align-items
aligns them vertically.
Setting a Gap between flex items
One very useful feature of flex is the gap
property.
Setting the gap
property on a flex container adds a specified space between flex items, similar to adding a margin to the items themselves.
Adding gap: 8px
to the centered example above produces the result below:
See the Pen flex-alignment example by TheOdinProject (@TheOdinProjectExamples) on CodePen.
There’s more for you to learn in the articles below, but at this point you can surely see how immensely useful flexbox is. With just the properties we’ve already covered, you could already put together some impressive layouts!
Knowledge check
💬 DISCUSS: The following questions are an opportunity to reflect on key topics in this lesson. If you can’t answer a question, click on it to review the material.
Additional resources
- 🔖 Bookmark this FLEXBOX VISUAL CHEATSHEET !!!
- 🐸 Flexbox Froggy is a funny little game for practicing moving things around with flexbox.
- 📚 Articles:
- This beautiful Interactive Guide to Flexbox covers everything you need to know. It will help reinforce concepts we’ve already touched on with some really fun and creative examples. Spend some time here, some of it should be review at this point, but the foundations here are important!
- Typical use cases of Flexbox is an MDN article that covers some more practical tips. Don’t skip the interactive sections! Playing around with this stuff is how you learn it!
- The CSS Tricks “Guide to Flexbox” is a classic. The images and examples are super helpful. It would be a good idea to review parts 1-3 and part 5 (don’t worry about the media query parts)
- Aligning Items in a Flex Container goes into more depth on the topic of axes and
align-items
vsjustify-content
.
Acknowledgement
Content on this page is adapted from The Odin Project and most images are from Interneting is Hard.