css flexbox, gutters, and negative margin

2021-03-03

 | 

~3 min read

 | 

410 words

I missed the days of using float to design layouts on the web. Note, I don’t miss them, I missed them. I count myself lucky. Fortunately things have progressed considerably since the early days! Still, despite all of our progress, we still have some old habits that die hard.

For example - grid layouts make gutters a first class concept with gap, but what do you do if you can’t use grid? Or want to use sub-grids but have customers who aren’t on Firefox?

Flexbox is still a great alternative to many things and it can even support gutters in its way.

Looking at MDN’s guidance for creating gutters with Flexbox, the negative margins jumped out to me as slightly bizarre. It was only after talking to a colleague about why that might be the case that it started to click.

Let’s look at an example (and the CodePen for interactivity).

We have a number of elements that we want to layout in nice rows. Because this is made up, we’ll pretend that all of the elements are uniformly sized. We want there to be a eight pixel gap between each element and eight pixels between each row.

<div class="wrapper">
    <div class="container">
        <div>block a</div>
        <div>block b</div>
        <div>block c</div>
        <div>block d</div>
        <div>block e</div>
        <div>block f</div>
        <div>block g</div>
        <div>block h</div>
        <div>block i</div>
        <div>block j</div>
        <div>block k</div>
        <div>block l</div>
    </div>
</div>
.wrapper {
    border: 2px dotted green;
    width: 180px;
}

.container {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    width: 180px;
    border: 1px dotted red;
}

.container > * {
    width: 50px;
    margin-left: 8px;
    margin-top: 8px;
    border: 1px dotted blue;
}

This yields a nice grid like layout. There’s just one problem: it’s askance.

Notice how the container has a gap on the top and left but abuts the rows on the right and bottom?

We can fix this by reversing the margin with the parent - i.e., the container:

Let’s tweak our CSS:

.container {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
-  width: 180px;
+   margin-left: -8px;
+  margin-top: -8px;
  border: 1px dotted red;
}

Now, notice how the red dotted lines shifts left and up to the point where it’s outside of the box altogether? That’s what the negative margins are doing.

Since each box inside the container is pushed to the right and down, we’re shifting the entire container left and up to make sure everything stays aligned. Voila! Gutters that aren’t askance!


Hi there and thanks for reading! My name's Stephen. I live in Chicago with my wife, Kate, and dog, Finn. Want more? See about and get in touch!