A horizontal layout of squares and circles

is a new and very powerful CSS layout module, one completely divorced from web practices of the past. Most of the online coverage of the module has focused on details of the specification, which is long, complex, and somewhat arcane. In contrast, there’s relatively little detail on how flexbox can be used by the designer-developer to solve everyday layout problems: thus, this article, the first in a three-part series.

At the basic level, flexbox has three features that are fundamental to design, but which have long been difficult or impossible to achieve in CSS: alignment, distribution, and ordering.

Before we begin, there are a few things to be aware of:

  • Flexbox went through three iterations before finally settling into the spec we have today. Each of those iterations had different property names, with appropriate vendor prefixes in different browsers. Right now we’re at the point where all current browsers support the unprefixed final spec, but working backwards is something of a minefield. For this reason, I very strongly recommend you use a recent browser to create and test your code using the final version of flexbox, then work backwards in each browser to achieve support In older versions. Trying to write flexbox code to support all browsers at the same time is an exercise in frustration.
  • While flexbox can work with other CSS layout systems, it is important to abandon previous assumptions and practices in web page layout before starting work in the new system. It has a very different way of working, and you’ll only be stymied if you bring presuppositions to it.
  • You’ll hear occasional claims of “what flexbox is for”. While it is true that other layout systems will quickly supplement flexbox – grids and regions among them – the claim is not exclusively true.  CSS is not semantic, and no part of it has a pre-ordained role. You can use any CSS to achieve anything you wish; the only question is how effectively the code accomplishes your goal. As we’ll see, flexbox solves a lot of layout problems that designers face today.
  • The previous incarnations of flexbox make researching it somewhat treacherous: it’s easy to find an article written without an entry date, only to discover that you’ve been reading an interpretation of the (now obsolete) Flexbox 2009 spec. Play close attention, and be careful.

A Basic Example of Flexbox in Action

Let’s take three simple <div> elements and place them inside another container:

<div id="item-container">
	<div class="circle"></div>
	<div class="square"></div>
	<div class="circle"></div>
</div>

Now let’s set the inner div elements to look like their class names, while setting display: flex on the outer container:

#item-container {
	display: flex;
	background-color: hsl(34,88%,90%);
}
.square {
	height: 200px; width: 200px;
	background-color: hsl(50,88%,50%);
}
.circle {
	border-radius: 50%;
	width: 150px;
	height: 150px;
	background-color: hsl(22,88%,50%);
}

The result looks like this:

There’s a few things to take note of immediately:

  • The most common flex properties are applied to the parent element, rather than the individual children. This is a frequent cause of confusion, as most web developers are accustomed to controlling individual elements, rather than styling them through their parents.
  • Each immediate child of the flex container is considered a “flex item”. However the content inside the children do not inherit anything special, and can take any CSS you wish. Because each child is a flex item, you may find yourself “protecting” content by wrapping it in a div or other element, making it the flex-child rather than the inner content.
  • “Block”, “inline”, “float” and “text-align” have no meaning in the context of flex items.
  • By default, flex items are aligned at their tops and to the left of the flex container.

Flex Alignment

As a first step, let’s change the horizontal alignment of the flex items. The “left” of the flex-item distribution is known as flex-start. We’ll change it to the end:

#item-container { justify-content: flex-end; }

Nothing outstanding so far, but let’s take a look at a few other possibilities.

#item-container {
	justify-content: center;
}

That’s pretty neat: gaining a similar design in traditional CSS would usually require at least one more element and some extra declarations to get the same result. But we’re not done yet:

#item-container {
	justify-content: space-between;
}

Now we’re talking. space-between maximizes the distribution of elements within their container. This remains true whether there are two flex items elements or a dozen.

One more:

#item-container {
	justify-content: space-around;
}

It’s perhaps easiest to think of this as “margin: 0 auto that works for everything”. The flex items are evenly distributed by default, but each is centered inside the space it is given.

You’ll note that all movement so far has been restricted to the horizontal plane. What about vertically?

#item-container {
	justify-content: space-between;
	align-items: center;
}

The flex items move along what the flexbox model refers to as the “cross-axis”.  The central square, having no vertical space in which to move, stays where it is. Effectively, this aligns elements on their centers, along a horizontal axis. Other values include flex-start (the default, equivalent to “align top”), flex-end (“align bottom”) and stretch.

I also said that flexbox was the first CSS layout system that would allow you to order items. Let’s try a simple example of that: placing the square before the circles, rather than between them:

.square { order: -1; }

Now that’s really cool. Flexbox effectively frees our page content from the shackles of source order: traditionally, whatever came first in our HTML had to be displayed first on the page. This change is well out of the reach of traditional CSS, into a space previously occupied solely by JavaScript.  It’s important to understand that your original HTML code remains the same: use View Source in your browser to prove it.

There’s a great deal more to explore in , so much so that it can quickly become overwhelming. Hopefully this article has provided a good start; in future articles I’ll demonstrate other ways in which flexbox can help make previously “impossible” page designs achievable by designers.

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.
Check out the CodePen demo for this article at https://codepen.io/dudleystorey/pen/jLecs