Exercises in Flexbox: Simple Web Components
In this tutorial we are going to practice building web components with two exercises: we’re going to use Flexbox to build a “thumbnail list” and a “sidebar” component.
Flex
In case you aren’t yet aware, “Flexible layout” (Flexbox) is a CSS feature which provides an efficient way to layout, align and order items in a given container. Partnered with Grid and other specifications it makes up a more complete layout module, in answer to floats and tables and other hacks web designers have been using over the years.
With Flexbox, items can be laid out in any direction and can adjust their sizes, either growing to fill unused space or shrinking to avoid overflowing the parent.
Exercise 1: Thumbnail List Component
Lists are used to display rows of information, such as a playlists, user details, or movies. Often, these lists contain images that we know as “thumbnails”. Aligning images with traditional methods can be a little tricky and inconsistent, but with Flexbox we can style a list component with minimal CSS.
For this component let’s use a <ul>
element with list items <li>
:



We will use flexbox to create the layout for our .list-item
, giving each one two direct child elements like this:



This figure illustrates how flex-shrink
and flex-grow
behave. The .list-item__image
item will never shrink, and the .list-item__content
will take up the remaining space in the li
container.
This will be the HTML structure for each one:
1 |
<li class="list-item"> |
2 |
<div class="list-item__image"> |
3 |
<img src="images/image.png" alt="Image"> |
4 |
</div>
|
5 |
<div class="list-item__content"> |
6 |
<h4> Name Surname </h4> |
7 |
<p> Info </p> |
8 |
</div>
|
9 |
</li>
|
And the basic CSS will look like this:
1 |
.list-item{ |
2 |
display: flex; |
3 |
}
|
4 |
.list .list-item__image{ |
5 |
flex-shrink: 0; |
6 |
}
|
7 |
.list .list-item__content{ |
8 |
flex-grow: 1; |
9 |
}
|
Here’s what these basic styles give us:
You’ll see the avatars are positioned to the left, the details to the right.
I pulled the user details from randomuser.me. By adding some extra styling (wrapper styling, a border radius on the images, basic typography, background colors etc.) we will get this:
You can see the full CSS on CodePen and play around with it. For example, if you move .list-item__image
after .list-item__content
in the HTML you will get a thumbnail list with images on the right side without having to use any additional classes or styles.
Exercise 2: Sidebar Component
Many websites and web applications use a sidebar for navigation. In this exercise we are going to build a reusable sidebar component using Flexbox.



The layout contains three main parts:
- logo placeholder
- navigation
- user profile block
Typically, the tricky part of building this kind of layout is placing the profile block at the bottom of the sidebar.
Using Positioning
1 |
.sideabr{ |
2 |
position: relative; |
3 |
padding-bottom: 70px; |
4 |
}
|
5 |
.user-profile{ |
6 |
position: absolute; |
7 |
bottom: 0; |
8 |
}
|
With this “traditional” solution, we assume that the user profile’s height will be 70px. So we give 70px of padding to the bottom of the sidebar in which to place it. But what if at some point we redesign the profile box so its height changes? Or we decide to place it at the top? In these cases, we’d need to create additional classes for the sidebar or modify the current styles, neither of which are ideal.
The Flexbox Way
With Flexbox we can solve this problem sensibly. We will use the same technique that we used in the thumbnail component, but with a small difference. We will change the direction from horizontal to vertical with flex-direction: column;



The top and bottom parts of the component remain “un-shrinkable”. The central element .sidebar_nav
will fill the rest of the space thanks to its flex-grow: 1;
.
So, here’s the HTML markup:
1 |
<!--Sidebar Component-->
|
2 |
<div class="sidebar"> |
3 |
<div class="sidebar__logo"> |
4 |
<h3> Sidebar </h3> |
5 |
</div>
|
6 |
<ul class="sidebar__nav"> |
7 |
<li> Home </li> |
8 |
<li> About Me</li> |
9 |
<li> Portfolio</li> |
10 |
<li> Contact Me</li> |
11 |
</ul>
|
12 |
<div class="sidebar__profile"> |
13 |
<img src="images/profile.jpg" alt="Profile Photo"> |
14 |
<h4>Name Surname</h4> |
15 |
</div>
|
16 |
</div>
|
And our basic styles:
1 |
.sidebar{ |
2 |
display: flex; |
3 |
flex-direction: column; |
4 |
height: 100%; |
5 |
}
|
6 |
.sidebar__logo h3{ ... } |
7 |
|
8 |
.sidebar__nav{ |
9 |
flex-grow: 1; |
10 |
list-style: none; |
11 |
padding: 0; |
12 |
}
|
13 |
|
14 |
.sidebar__profile{ ... } |
To recap, the .sidebar
component has a property flex-direction: column
which will transform the flow of its children elements from horizontal to vertical.
.sidebar__nav
has the property flex-grow: 1
which means that it will take all the available space in the container and will push .sidebar__profile
box to the bottom of the sidebar.
With this approach, we don’t need to worry about the profile box height. So, what does this give us?
This is the final result of the sidebar with additional styles, including some icons pulled in from Fontawesome.
Conclusion
Flexbox has really changed the way we can think about layout on the web, and happily it’s supported by all modern browsers. In this tutorial, we used just a few properties of Flexbox, but there are many others as you may imagine. In the next “Exercises in Flexbox” tutorial, we will build more intermediate components, covering other Flexbox features along the way.