4 Classic CSS Problems solved with Flexbox

CSS has always been a major cause of headache for web developers. Even achieving the seemingly simple layout of header, content, sidebar and footer (known as the Holy Grail Layout) has historically been a challenge and hacks like clearfixes were developed out of necessity.  Fortunately Flexbox offers more semantic, simple, and robust solutions to many common CSS layout problems. This article will showcase 4 common problems that Flexbox solves.

Centering Things

Centering an element within it’s parent in CSS (especially vertically) has traditionally been a pain. Combining relative/absolute positioning with transforms is possible, but often can require non-semantic wrapper elements and just seems hacky. The great thing about centering things with flexbox is that you have options – you can center by defining properties on the parent element or the child element (by using margins), and it can also be used for centering text. Look at the examples below:

1

1

1

One particular place where center alignment can be hard is headers with navigation menus. It is common to have a branding logo on the left and some links on the right, and while a float based approach can achieve this, it cannot automatically center the logo with the nav links. Here is an example of a flexbox based approach that takes advantage of thealign-items property:

1

Notice that this requires no use of vertical padding or margin for alignment, so if the height of the logo changes then the position of the links will automatically adjust. This is much more maintainable!

Keeping the Footer at the bottom of the page

Most pages on the web are taller than the height of the viewport, and users can scroll down the page to see content below the fold of the screen. In some rare cases, however, the viewport can be taller than the page. This is usually because the page doesn’t have a lot of content or maybe the user’s screen is just very large. Check out the following pen (you’ll need to open the full page view) to see an example of this problem.

1

This looks pretty bad – it would be much better to have the footer stick to the bottom of the screen. One simple approach to this problem would be to set the height of the content element, but knowing exactly what value to set it to is tricky. Setting the height to too small a value fails to solve the problem, and setting the height to too large of a value may result in a lot of empty space. On top of that, the space that needs to be filled varies across screen widths.

The following pen shows how this can be solved elegantly with flexbox by setting the body’s minimum height to that of the viewport and then allowing the content element to fill any vacant space:

1

Much better!

Keeping Columns at equal heights

Although floats can be used to lay content out in a row, setting columns to equal heights with this approach can be quite difficult. In fact, Foundation designed a plugin called Equalizer to address this problem specifically: https://foundation.zurb.com/sites/docs/equalizer.html.

Without Javascript set to explicitly watch and set columns heights, floated columns will look like this:

1

Using Javascript to solve such a simple, common layout problem is not ideal, and Flexbox has emerged as a much better alternative:

1

Once again, part of the beauty of the flexbox solution is the options that it gives you. The columns stretch to equal heights because the align-items property defaults to “stretch”, but you can manually set it to “flex-start” to emulate the float-based approach (but with no need to clearfix!), or even set it to “flex-end” for bottom alignment.

This layout is particularly nice when each column has an element at the bottom of it, and we want these elements (buttons, for example) to be at the same level. To create this effect, we combine this code and the code used for sticky footers, and can center the button with align-self: center;

1

Laying out an unknown number of Columns

Float based layouts have the ability to evenly distribute columns in a row, but they rely on math. Two column layouts should set widths to 50%, four column layouts should set widths to 25%, and three column layouts should set widths to 33.3% (or better yet, set widths to calc(100%/3)).  Apart from the arithmetic that this requires, the real problem is that we need to know the amount of columns explicitly. In the majority of use cases, this is no problem, but sometimes the number of columns in a row is variable (think CMS). In this scenario, Flexbox shows its value. The flex property allows us to define how space is occupied without worrying about the math. Checkout the demo below:

1

Handy, eh?

Note: Although this post is focused on CSS and Flexbox, the Javascript written for the purpose of this demo is interesting in itself. Check out how ES6 and functional programming can be combined with the vanilla DOM API to create the slideshow effect without writing many lines of code or requiring any dependencies.