# Preventing Orphans in Flexbox

Using `:nth-last-child`

to avoid a standalone element.

*Extra*

Preventing orphan elements with pure CSS—more on that in a bit—might not be something you’ll actually want to pursue, but it gives us a good reason to learn more about the `:nth-last-child`

selector.

## Some groundwork

While `:nth-child(3)`

can be used to select the third child inside a container, `:nth-last-child(3)`

selects the antepenultimate child, because we start with the last child and count backwards. To select not just one but every third child, we use `:nth-child(3n)`

or `:nth-last-child(3n)`

.

We can add positive or negative offsets. E.g., to select each child that follows immediately after every third child, we put `3n + 1`

inside the parentheses.

Let’s keep the focus on *3n + 1*, as this is where in the depicted example both *nth-child* and *nth-last-child* target the same elements. Which is simply due to the number of elements we have in total. If we add children to the container, things run out of sync. (In this particular case, only if we add one or two elements. Adding three elements brings things back in sync, courtesy of the *3n* part in our selector. And so on.)

Now if—for some reason—we only want to target children where both *nth-child* and *nth-last-child* apply, we simply combine both selectors.

Do you see where this is going? If not, maybe it’s time to wrap our children onto multiple lines.

## Detecting a single element in the last row

The Flexible Box Module, usually referred to as flexbox, was designed as a one-dimensional layout model,

is what MDN has to say about flexbox. While there are key differences to CSS Grid Layout, which gives us two dimensions right out of the gate, flex items may also wrap, thanks to `flex-wrap: wrap`

.

Let’s make the container wide enough to fit three (yes, *3n* correlation) children. We wrap after every third child, which means *3n + 1* children will be first in their row.

In this flex-wrap scenario, only the container on the left happens to produce an orphan in the last row, which is also the one where *nth-child* and *nth-last-child* meet. For our CSS to apply only in cases where the total amount of children is *3n + 1*, we once again combine the two selectors.

Doing so, we’ve selected all children that are first in a row, in other words the ones in the first column. And we’ve limited our selection to containers that produce an orphan child in the last row, while containers with a children count other than *3n + 1* are unaffected.

As we are not interested in these individual first-column children, we now reduce this even further, and only select the first child, by adding `:first-child`

. As *first-child* also takes care of what we needed *nth-child* for, we may conveniently reduce it to `:first-child:nth-last-child(3n + 1)`

.

Having selected the initial child in orphan-producing containers, we can now either do something with that child directly, or select any child that follows using the general sibling combinator.

Here we are, ready to **prevent an orphan element in the last row.** The idea is to create an empty slot elsewhere, so that a second child gets pushed down into the last row. We choose a child and add a margin (left or right) to it, with the margin value being the element width. The use of margins is the reason why this will only work in a flexbox container, but not in grid. A margin on the left will shift the chosen child and all that follow. A margin on the right will only shift those after the chosen child. Which child should be the chosen one? That depends on the visual effect you want to achieve.

## Interactive playground

This solution will work for any number of rows and columns. For fewer or more columns, simply adjust the container width and replace *3n* with your desired value. To get an even better understanding, head over to my interactive version on CodePen, where you can play around with different settings.

## Postscript: A word on `gap`

Adding a gap between the children is possible, but at the time of writing, setting a `gap`

on flex containers is not supported in Safari. This can be achieved by setting a margin on each item, and negative margins on the container. No matter which one you add, `gap`

or `margin`

, the gap has to be taken into account when calculating the width of the container, and offsetting the items.