Flexbox Layouts
This chapter will explore the Flexbox layout model, one of the most powerful and flexible ways to design responsive web layouts with CSS. In later chapters, we will cover what "responsive" design is in more detail, but for now, the short answer is to ensure that your web page looks good on all device sizes (from your phone to your desktop).
Flexbox (short for Flexible Box) allows you to create complex layouts with simple and intuitive syntax. Unlike the float
property, we set our parent container to display: flex;
to use it. This changes the default behavior of our elements. Because this single property changes the behavior of the container and its children, we will use a lot of new terminology in this section. Don't worry about remembering everything; you can always dive back here when needed.
Note: If you need a reminder of how different display values impact your layout, here is the chapter in which we covered it.
Before we dive into examples, let's understand some basic Flexbox terminology:
- Flex Container: The parent element that contains flex items. To create a flex container, you set the
display
property of the parent toflex
orinline-flex
. - Flex Items: The direct children of the flex container.
- Main Axis: The primary axis along which flex items are laid out (default is horizontal).
- Cross Axis: The axis perpendicular to the main axis.
Here's a diagram showing each of these to visualize these concepts better:
Creating a Flex Container
To start using Flexbox, you need to define a flex container.
This is as simple as adding the following to your parent container:
.container { display: flex; }
Here's an example with the children being given fixed heights and widths:
Now that we have a flex
container, let's alter some properties to show you how it affects things:
Main Properties of a Flex Container
flex-direction
- Defines the direction of the main axis.
- Values:
row
(default),row-reverse
,column
,column-reverse
.
.container { display: flex; flex-direction: row; /* Horizontal layout */ }
Here's our initial example with all of the different directions applied:
The one thing to notice is how the change of values from row
to column
changes the axis:
The arrow directions are reversed when we apply the row-reverse
or column-reverse
.
justify-content
- Aligns flex items along the main axis.
- Values:
flex-start
(default),flex-end
,center
,space-between
,space-around
,space-evenly
.
.container { display: flex; justify-content: center; /* Center items horizontally */ }
Here's an example of all of them in action with a flex-direction: row;
container:
Edit the CodePen and try it out with a flex flex-direction: column;
.
align-items
- Aligns flex items along the cross-axis.
- Values:
stretch
(default),flex-start
,flex-end
,center
,baseline
.
.container { display: flex; align-items: center; /* Center items vertically */ }
To show how each works and their effects on the children, here's a CodePen. The only element with a fixed height in this list is "Box 2", and that's so you can see how the stretch
or default setting "stretches" your child elements:
flex-wrap
- By default you'll notice that elements don't wrap or go to a new line in a flex container. We can change this behavior by using
flex-wrap
. - Values:
nowrap
(default),wrap
,wrap-reverse
.
.container { display: flex; flex-wrap: wrap; /* Allow items to wrap onto multiple lines */ }
Here is a CodePen to play around with and see it in action:
Flex Items Properties
Flex items have properties that control their size and growth behavior. This can also override at an item level the default behaviors inherited by the parent flex container:
flex-grow
- Defines the ability for a flex item to grow relative to the rest of the items.
- Value: A number (default is
0
).
.item { flex-grow: 1; /* Items will grow to fill available space */ }
Here's it in action with some different numbers:
You can see that you can define ratios in the numbers, and it'll fill the space. In the second example, if only one item has the flex-grow
property, it can take the remaining space.
## flex-shrink
- Defines the ability for a flex item to shrink if necessary. You can think of it as the element you don't mind if it gets squashed.
- Value: A number (default is
1
).
.item { flex-shrink: 1; /* Items will shrink if needed */ }
Here's a CodePen to play with:
flex-basis
- Defines the default size of an element before the remaining space is distributed.
- Value: A length value or
auto
(default isauto
).
.item { flex-basis: 100px; /* Set initial size of items */ }
Open the CodePen and you can see what happens when you resize the window:
align-self
- Overrides the
align-items
property for individual flex items. - Values:
auto
(default),flex-start
,flex-end
,center
,baseline
,stretch
.
.item { align-self: center; /* Center this item on the cross axis */ }
Here's a CodePen to try out the different values:
Practical Flexbox Layout Example
Let's create a more complex layout using Flexbox, including a header, sidebar, main content, and a footer.
Here's the CodePen so you can explore the code.
- The
.container
class is set todisplay: flex
withflex-direction: column
to arrange its children vertically. .header
andfooter
: These elements span the full width of the container and have padding and background colors for visual distinction.- The
.main
class is a flex container itself, arranged horizontally by default. It contains the sidebar and main content. - The
.sidebar
has a fixed width, while the.content
grows to fill the remaining space usingflex-grow: 1
.
I hope you can see that you can do pretty much anything you want in a page layout with Flex. There was some content here, so don't forget to practice these skills. In the next section will cover how to use CSS grids for layouts.
As a cheatsheet, one of my most visited guides on is this A Complete Guide to Flexbox. Worth bookmarking for when you are trying to figure things out.