SITERAW

Flexbox layouts

In the last two chapters we saw how to build the basic structure of our pages in HTML and how to manage the dimensions of our elements with CSS.

It's time for the long awaited moment: when we learn all about CSS layouts.

In other words we'll see how to change the position of the items on our web page, align certain elements and choose precisely where each and every block will appear.

This is the final piece of the puzzle that we allow us to build actual websites that look like something.

And the name of this piece is Flexbox... remember that name because we'll be using it often during this chapter.

In fact, we might as well start out with an introduction to Flexbox.

We'll cover where it began, why it was invented and especially what role it fills in web designing and web development.

And don't worry... the practice will come soon enough.

Introduction to Flexbox

Before we start introducing every Flexbox property, and trust me there are many, let's give a little introduction to the Flexbox model.

We will first go over the history of Flexbox after which we will introduce the basic theory behind its operation.

A history of Flexbox

Flexbox stands for Flexible Boxes and is a relatively new addition to the world of web designing.

The flexbox model
The flexbox model

Prior to Flexbox, designing the layout of web pages in CSS was a notoriously intricate matter.

Here are a few of the ways web developers attempted to address this issue, in somewhat chronological order.

  • At first, websites were designed using HTML tables. This predates even the CSS language and is considered severely obsolete (0/10 wnb).
  • Then CSS appeared and we started building website layouts using the float property (5/10).
  • Another method was to create inline-block elements which had their own specific attributes. This was only a marginal improvement over the float method and it came with its own set of drawbacks (5.5/10).
  • Finally, since CSS3, we can now use the Flexbox model. How good is it? Keep reading.

Each successive method was conceived as an answer to the limitations of its predecessors.

Flexbox was specifically designed to be flexible, as its name implies, but also to accommodate to the challenges of modern web development: integration with Javascript and other client-side languages, support of various screen resolutions and rendering devices and so on.

The use of Flexbox ensures that elements behave in a predictable manner even when the page layout must accommodate to different screen sizes and display devices.

The Flexbox model

So the question you're probably asking yourselves right now is: how does Flexbox work?

How does Flexbox work?

The principle behind Flexbox layouts is remarkably simple: you define a container in which you place your elements.

A container which holds one or more nested items.

As long as you remember that rule you already know 99% of what there is to learn about Flexbox.

You can also define multiple containers one after the other on the same web page, it will be up to you to create as many as necessary to get the layout you want.

Let us begin by studying the behavior of a container.

A flexbox container
A flexbox container

Your Flexbox containers (and items) can be anything as long as they are block-level HTML elements.

In one of our previous example, we used the <section> tag as a container for both the <article> and <aside> items.

You probably remember the following code excerpt.

<section>
    <article> [...] </article>

    <aside> [...] </aside>
</section>

But we can also use a more general example with <div> tags.

<div id="container">
    <div class="item">Item 1</div>

    <div class="item">Item 2</div>

    <div class="item">Item 3</div>
</div>

The container and items are respectively distinguished by the ID and class attributes.

I already know that! The blocks will simply be placed one underneath the other.

True.

Since these are block elements they will follow the typical rules of the CSS box model that we saw in the previous chapter.

Let's add some colors to the items to see how they are organized.

Default block positioning
Default block positioning

Nothing new so far, this is the normal behavior of blocks.

But what if we want to modify this behavior?

That is the entire purpose of the Flexbox model.

Element direction

That was simply the theory, now let's discover the practical applications of Flexbox starting with the direction of the flow of these elements.

But before that we need to define our Flexbox container.

To do so you must add a single property to whichever element you want as your container, the display property.

We already know a few of the values it can take such as block or inline, so let's introduce a new one... flex.

Here is the CSS code we are working with.

#container { display: flex; }

With this simple adjustment, our blocks are now placed side by side by default.

Flexbox block positioning
Flexbox block positioning

There are of course many more ways to handle the direction in which the elements are placed.

Element direction

Flexbox allows us to organize nested elements in the desired direction.

The property for doing so is flex-direction, it's once again applied to the container and affects all child items.

Here are the values it can take.

  • row : organized on a row (default)
  • column : organized on a column
  • row-reverse : organized on a row in reverse order
  • column-reverse : organized on a column in reverse order

Let's try appending our example with this new property.

#container
{
    display: flex;
    flex-direction: row-reverse;
}

And the result.

Flexbox reverse item order
Flexbox reverse item order

You can see the difference: the blocks are now in reverse order.

The HTML code remains identical, only the flex-direction property was added to the CSS code.

You can apply any of the indicated values to this property.

Below is a visual example of their effects.

Flexbox direction illustration
Flexbox direction illustration
Keep in mind that row and row-reverse depend on the writing mode so in right-to-left context they will be reversed respectively.

Handling the wrap

By default, blocks inside a container will try to stay on the same horizontal line which can lead to content overflowing and other graphical inconveniences.

Flexbox somewhat solves this problem by dynamically reducing the width of each item should their combined dimensions exceed the maximum space available.

But you can also define the way you want the elements to wrap with the flex-wrap property.

Here are the values it can take.

  • nowrap : all flex items will be laid out in a single line (default)
  • wrap : in case of overflow the items will wrap onto multiple lines from top to bottom
  • wrap-reverse : flex items will wrap onto multiple lines from bottom to top

Here is a visual illustration of this property.

Flexbox wrap demonstration
Flexbox wrap demonstration

Going back to our example, we could add the following line of code.

#container
{
    display: flex;
    flex-direction: row-reverse;
    flex-wrap: wrap;
}

This would force a line-break in case of item overflow.

Flexbox wrap illustration
Flexbox wrap illustration
For purposes of brevity, you can use the flex-flow shorthand property which combines the values of both flex-direction and flex-wrap. Its syntax is flex-flow: <direction> <wrap>.

Flexible alignment

Let's review a bit of what we know.

Items are organized either horizontally, by default, or vertically.

This defines what is called the main axis. There is also a secondary axis (cross axis) perpendicular to the main axis.

  • If your elements are organized horizontally, the cross axis is vertical
  • If your elements are organized vertically, the cross axis is horizontal

Why am I telling you this?

Because we're about to learn how to align our elements both on the main and secondary axes.

Alignment on the main axis

We'll start with the simplest illustration, when elements are aligned horizontally (by default).

The property we need to change their alignment is justify-content.

It can take these values.

  • flex-start : items are packed toward the start line (default)
  • flex-end : items are packed toward to end line
  • center : items are aligned at the center of the container
  • space-between : items are aligned with equal spacing between them
  • space-around : same as above except they leave a natural padding space at their extremities

We can add this property to our demonstration code.

#container
{
    display: flex;
    justify-content: space-between;
}

But the best is still to test all possible values and see the results.

See the figure below for a visual demonstration of these values.

Flexbox justify content illustration
Flexbox justify content illustration

You see how the elements are aligned differently in each different case? With a simple property, we can intelligently arrange our elements the way we want.

It also works if your elements are in a vertical direction. In this case, the vertical axis becomes the main axis and justify-content functions much in the same fashion.

#container
{
    display: flex;
    flex-direction: column;
    justify-content: space-between;
}

Try it out and see the results for yourself.

Alignment on the secondary axis

If our elements are placed in a horizontal direction (row), the secondary axis or cross axis is vertical.

And conversely if our elements are in a vertical direction (column), the secondary axis is horizontal.

To modify the alignment along the cross axis the property we need is align-items.

It works very much like justify-content but in the perpendicular direction.

Here are the values the align-items property can take.

  • stretch : items are stretched over the entire axis (default)
  • flex-start : items are stacked toward the start of the container
  • flex-end : items are stacked toward the end of the container
  • center : items are stacked to the center of the container
  • baseline : items are stacked such that their baselines align

You can see case by case illustrations in the figure below.

Flexbox align items illustration
Flexbox align items illustration

In these examples we assume that our elements are in a horizontal direction but it works just as well vertically.

And this concludes our work with the Flexbox model.

Everything we learned in this chapter, and the two anterior ones, will be useful for what we're about to do next.

Indeed we won't be covering anything new in the next chapter, rather we'll see how to build an actual website from scratch... architecture, design, layout and all.