Getting Good with Flexbox

Long before flexbox became a thing we as web designers struggled to use floats, display properties, and clear methods to achieve the different types of layouts within our web pages. If you’re like me you still have issues with this approach. This method worked and still does, but it’s quite cumbersome and sometimes hard to maintain or control.

With the recent introduction of Flexbox, all things are beginning to transform for a modern day developer. In due time browser support for the new module will be available but until then you can take advantage of this series by gaining an understanding of what Flexbox is and why it reigns supreme over the old way of crafting layouts with CSS alone. Join me as I guide you through a short write up about Flexbox to explain the semantics, inner-workings, and how to use it in your projects today.

What is Flexbox?

Flexbox otherwise known as flexible box is a module that aims at providing a better approach to constructing layouts within a given container. The idea is to properly align or distribute space between elements within the parent container to maximize screen real estate no matter the viewport size. This gives much meaning to the word “flex” as the elements I spoke of can be altered or transformed with a few specific properties via CSS.

A flex container expands elements to fill any available free space or shrinks them to prevent the content from overflowing. Direction plays a massive role within a flex container. You can define vertically based layouts or horizontally based layouts with a single line of CSS. This is great for pages with content of repetitive characteristics, like a blog post or gallery type of layout. You can also think bigger in terms of a page’s main container and sidebar.

Larger scale layouts are probably more worthy of a grid layout as opposed to a flexible layout.

You may think just writing display: flex will initialize the layout but because flexbox is a module and not a single property there are many properties that go along with it.

Parent Container (flex container)

The flex container makes it all happen. You will need this container to maximize the “flexible” qualities of flexbox. First I’ll go over the properties and values you may run into with the flex container and then move on to the properties and values of the children or flex items (items within flex container).

Display

In order for elements to “flex” you need to first define a container element that wraps around children.

<div class="flex-container">
    <div class="flex-item"></div>
    <div class="flex-item"></div>
    <div class="flex-item"></div>
    <div class="flex-item"></div>
    <div class="flex-item"></div>
    <div class="flex-item"></div>
</div>

then within your CSS you need to declare the display to be flex like this.


.flex-container {
    display: flex;
}

flex-direction

After your container is defined you have a few options within a property known as flex-direction to define. There are four different types of values for this property:

  • row (the default): this reads left to right ltr or right to left rtl
  • row-reverse: (the opposite of row): right to left ltr or left to right rtl
  • column: this displays in the same order as row but from top to bottom
  • column-reverse: this displays in the same order as ‘row-reverse’ but displays bottom to top

Defining this property looks like this. You would add this to the same parent flex container as above.


.flex-container {
    display: flex;
    flex-direction: row;
}

flex-wrap

More often than not the items within your flex container will be more than just a few. By default, these items will try to display all on one line. You can alter this by using the flex-wrap property. There are three different types of values to assign to the property to alter the wrapping.

  • nowrap (the default): this displays in a single line from left to right ltr or right to left rtl.
  • wrap: use this value to display items in a multi-line fashion. Again you can alter direction here using the ltr or rtl values.
  • wrap-reverse: the opposite of wrap. This just alters direction.

.flex-container {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
}

flex-flow

flex-flow is more of a shorthand property for the combination of flex-direction and flex-wrap. To save some lines of code you may choose to write this instead of the previous two I mentioned which would look like this:


.flex-container {
    display: flex;
    flex-flow: row wrap;
}

Here I’m replacing flex-direction and flex-wrap with flex-flow. By doing this, I’m really just declaring both flex-direction and flex-wrap in one line. The first value is the flex-direction value and the second is flex-wrap.


.flex-container {
    display: flex;
    flex-flow: <'flex-direction'> <'flex-wrap'>
}

justify-content

Flexbox is smart about free space within a container. justify-content is a property used to decide what to do with that leftover space. There are four different values you can define:

  • flex-start (the default): all children are shifted toward the start of the parent container.
  • flex-end: all children are shifted toward the end of the parent container.
  • space-between: children are evenly distributed inline. The first child is at the start of the parent container and the last child is at the end of the parent container.
  • space-around: children are evenly distributed with equal space around the. The space between doesn’t always appear equal do to starting and ending axis from within the parent container.

.flex-container {
    display: flex;
    flex-direction: row;
    justify-content: space-around;
}

align-items

You can align the children of the parent flex-container just as you would by justifying them but just think of it on a different axis or baseline (similar to how our equator is the division of Earth). There are five values to set for this property:

  • flex-start: children align to the top of the parent container.
  • ‘flex-end’: children align to the bottom of the parent container.
  • center: children are centered across the axis.
  • baseline: children are aligned so their baselines are in line. If elements have different heights their baseline will change to align properly.
  • stretch: (the default): children stretch to fill the container but still respect their widths.

.flex-container {
    display: flex;
    flex-direction: row;
    justify-content: space-around;
    align-items: center;
}

align-content

Just as you can across axis’ and baselines you can align the children within the parent container if there is extra space to use up. This is great to use if you have multiple lines of content and are wrapping said content. There are five different types of values you can declare for this property:

  • flex-start: children lines are shifted towards the start of the parent container.
  • flex-end: children lines are shifted towards the end of the parent container.
  • center: children lines are shifted to the center of the parent container.
  • space-between: children lines are evenly distributed. The first line of children is at the start of the container and the last line of children is at the end of the container.
  • space-around: children lines are evenly distributed with equal space around each line.
  • stretch (the default): children lines stretch to take up any remaining space.

.flex-container {
    display: flex;
    flex-direction: row;
    justify-content: space-around;
    align-items: center;
    align-content: strech;
}

Children (flex items)

After having seen all the properties and values you can declare for the flex-container you may be overwhelmed and that’s okay! Flex is new to all of us, but it will start to feel more natural the more you use it. Just keep at it and it will seem simple to you before long.

The children of a flex container or flex items are obviously essential to making use of the flexible characteristics of Flexbox. The properties and methods I’m about to explain deal with altering specific characteristics of the children themselves as opposed to the parent container I discussed before.

order

The default order of the items or children is dependent on how it is authored in your HTML. You can change this with the order property. Based on how many children you have you can enter an integer as the value to optimize a specific order to match your needs.


.flex-item1 {
    order: 1;
}
.flex-item2 {
    order: 2;
}
.flex-item3 {
    order: 3;
}
...

This is particularly useful when establishing a layout of a page with elements like a header, footer, aside and so forth.

flex-grow

If you ever need a flex item to grow larger than another set of flex items that’s fairly easy to do. Simply define the flex-grow property and add an integer to dictate the appropriate width. The default is 0. If you were to set all items to 1 but change one of the items to 2 then that particular item would be twice the size of the others. You can not use negative values.


.flex-item {
    flex-grow: 1;
}

flex-shrink

If you need to revert or shrink a flex item the option is there with flex-shrink. Simply enter a non-negative number and flex does the rest.


.flex-item {
    flex-shrink: 1;
}

flex-basis

flex-basis defines the default size of an element before the remaining space is evenly distributed. If you set the second value to 0 the extra space around the element isn’t factored in. If you set it to auto kind of like margin then the extra space is distributed based on the flex-grow value/property.


.flex-item {
    flex-basis: auto; /* default */
}

flex

flex is a shorthand for flex-grow, flex-shrink, and flex-basis combined. The second and third parameters are optional. It is recommended to use this property as opposed to each of the three mentioned prior.


.flex-item {
    flex: 0 1 auto;
}

Real World Examples

Let’s build a quick navigation bar for a new header. This is purely an example but check out how easy Flexbox makes it!

Here’s the HTML I’ll start off with…


<ul class=“nav”>
    <li><a href=“#”>Home</a></li>
    <li><a href=“#”>Who We Are</a></li>
    <li><a href=“#”>What We Do</a></li>
    <li><a href=“#”>Case Studies</a></li>
    <li><a href=“#”>Get In Touch</a></li>
</ul>

It’s just a basic navigation menu with made within an unordered list.

The CSS is quite simple and I use the flex properties on both the ul and the a tags to make the view responsive.


.nav {
  list-style: none;
  margin: 0;
  background: #333;
  display: flex;
}
.nav a {
  color: #fff;
  display: block;
  text-decoration: none;
  padding: 1em;
}
.nav a:hover {
  background: #222;
}

@media all and (max-width: 800px) {
  .nav {
    flex-flow: column wrap;
    padding: 0;
  }
}

I’ve included a breakpoint to show how you can alter the flex orientation based on a screen width. This approach is what makes flex so great. No more floats or clears to deal with. Only simple declarations and parameters!

Finishing Up

The best way to learn Flexbox really can’t be taught in a blog post. You can use this as a reference but as with any type of code you need to learn by doing or building something. Take my examples and run with them. For even more knowledge and useful information try these links:

Flexbox – W3C
CSS Tricks – A Guide To Flexbox
Using CSS flexible boxes at MDN