I’ll show you some some really neat ways you can leverage the power of Flexbox in your websites and applications by recreating a layout from Spotify’s mobile app.
Here’s a live demo of what we’ll be building.
Open up this fiddle and click the Fork button to create your own instance of the fiddle.
The HTML pane contains the all the markup we need. Mostly just a bunch of divs and SVG icons. In the CSS pane, I’ve included a basic CSS reset as well some a few general styles.
The SVG icons present aren’t very visible at the moment. This is because I set the
fill property to a light color which blends in almost completely with the white background colour of the page.
Let’s move along now to writing the styles that will build up our app layout, taking advantage of the Flexbox layout model where necessary.
Style the phone screen
Add the following code below all the other rules in the CSS pane:
In order to emulate a phone screen, I’ve restricted the width of the layout to 450px while giving it a bright blue border to make the edges distinct. I’ve also made
.phone-screen a flex container (with
display: flex), and changed the direction of the
main-axis so that it runs in the block direction (from top to bottom).
Style the application header
We can achieve the header layout pretty easily with Flexbox. All we need to do is make
.header a flex container, and distribute the available space along the main axis between the flex items.
Style the main content area
The first thing we’ll do here is prevent the content from overflowing the phone screen. We can do this by adding the following code to the CSS pane:
Style the library categories
Next, we can style the categories at the top like this:
Here, I’ve aligned each icon and text with the
align-items property so that they are centered vertically.
Style the recently played section
We can center the Recently Played heading and give it a bottom margin like this:
Now, onto the playlists. Let’s apply a generic cover art styling, and make each playlist a flex container while distributing the available space between the flex items.
Hmmm that doesn’t look quite right. The problem stems from the names of each recently played playlist. Since they vary in length, the space that is available to distribute between the flex items isn’t the same across all the playlists.
We can fix this using a Flex property that I have not mentioned before:
flex-grow. It is applied on flex items, not the flex container.
The flex-grow property
flex-grow property determines how much of the available space in a flex container should be assigned to a flex item relative to the growth factor of the other flex items in the container. Its default value is
0 which means flex items do not grow beyond their intrinsinc or explicit width, if any.
flex-grow is set to a numerical value greater than
0, that flex item will grow in size if there is available space in the flex container after all the flex items have been laid out.
Let’s consider a few examples to really understand how
Consider the two boxes below. They are both flex items and have a width of
100px each. As you can see, there is plenty of space in the flex container that can be used somehow.
We could, for example, place that space between the flex items using
justify-content: space-between. Or we could make one of the flex items grow to fill up the remaining space with
flex-grow. Let’s do just that for
flex-grow: 1 to
.item2 causes it to swallow up all the available space and grow in size. Remember that
.item1 is still set to
0 (by default). So it remains
100px in width.
What happens if we give
flex-grow value of
1 as well? Let’s see:
Now, both flex items grow at the same rate. The available space is divided equally amongst them and, since they were the same width to begin with (
100px), the result is they are the same size after growing.
Let’s consider what happens if
flex-grow is set to
2 on one of the items:
.item1 grows at twice the rate as
.item2. Basically, the available space is divided in the ratio 2:1 and shared amongst the flex items as appropriate. The same thing happens if you set the value of
flex-grow to some other value. The available space will be distributed according to the ratio defined by the different flex grow factors.
Let’s head back to our app layout. Since the
flex-grow property of the other flex items in
.playlist is set to
0, this causes the whole space left in each container to be appended to
.info causing it to be the same size across all the playlists.
The styling of the Recently Played section is now complete and we can move on to the footer.
Style the footer
Let’s add some general styles for the footer elements:
Next up, we’ll align the elements in
.now-playing properly using Flexbox.
Looking good! Let’s wrap up by styling the navigation elements at the bottom:
Everything looks great now. What we did in that last bit was to space the nav items evenly, and align the icon and text in each nav item. We used
flex-direction: column to ensure that the icon is on top of the text, otherwise they would have been placed flushed against each other in the inline direction.
I hope this tutorial has showed you just how useful Flexbox is to layout elements in a user interface. I expect to have more tutorials on this subject, so stay tuned. Till next time!