The problem

I have a section with a background pattern that repeats on both axes. I wanted the vertical repeat to be aligned with the pattern’s height, so the pattern won’t have cut-offs.

Take the following design.

.section {
  --tile-width: 52px;
  --tile-height: 44px;
  background-image: url("pattern.png");
  background-size: var(--tile-width) var(--tile-height);
}

The Espresso Guide

Everything you need to pull a great shot at home: picking the right beans, dialing in your grind size.

Do you notice the cut-off at the bottom? This doesn’t look good. The first thing I thought about was to use the round value for the background-repeat property.

.section {
  background-repeat: round;
}

That worked.

The Espresso Guide

Everything you need to pull a great shot at home: picking the right beans, dialing in your grind size.

But my inner self said no. This is not the best solution, given the modern CSS tools we have. What I don’t like about this solution is that using the round keyword will force the pattern to shrink or grow.

In the following demo, click “Make it dance” and see how the pattern size changes.

The Espresso Guide

Everything you need to pull a great shot at home: picking the right beans, dialing

Let’s explore a better solution. If you don’t want to read the full article, you can jump to the solution below.

Using calc-size() and round()

The following solution works only in Chrome at the time of writing this article.

We can use calc-size() to get the auto height value, then use it with the round() function to round it to the nearest value we want. In this case, the value is the pattern’s height.

.section {
  height: calc-size(auto, round(up, size, var(--tile-height)));
}

At first glance, it looks like setting a fixed height. In fact, it works like min-height, as it calculates the auto height, then rounds it up to the nearest multiple of the tile height.

15

The Espresso Guide

Everything you need to pull a great shot at home: picking the right beans, dialing

It works great for different pattern sizes. All we need to provide is the tile height. Check out the following demo and play with the patterns:

The Espresso Guide

Everything you need to pull a great shot at home: picking the right beans, dialing in your grind size.

I wrote about the round() function if you want to dig more into it.

Rounding up or down?

Rounding the height up to the nearest multiple of the tile height will increase the height in most cases.

Switch between the up and down options in the demo below.

The Espresso Guide

Everything you need to pull a great shot at home: picking the right beans, dialing in your grind size.

I prefer down, as it doesn’t increase the height when it’s not needed, but it’s not a big deal.

What about padding?

We need to add vertical padding, so I thought about using round() for it, too. See below:

.section {
  height: calc-size(auto, round(up, size, var(--tile-height)));
  padding-block: round(up, 1rem, var(--tile-height));
}

The top and bottom padding is equal to the pattern’s tile height.

The Espresso Guide

Everything you need to pull a great shot at home: picking the right beans, dialing in your grind size.

Where rounding down feels a bit odd

Notice how the content is too close to the edge. This is where it starts to feel a bit odd, so in this case, I’d switch to rounding up for more expected behavior.

The Espresso Guide

Everything you need to pull a great shot at home: picking the right beans, dialing in your grind size.

The complete solution

Here is the complete CSS for the solution in the previews demos.

.section {
  /* This must match the size of the pattern image. */
  --tile-width: 52px;
  --tile-height: 44px;
  background-image: url("pattern.svg");
  background-size: var(--tile-width) var(--tile-height);
  padding-block: round(up, 1rem, var(--tile-height));
  height: calc-size(auto, round(up, size, var(--tile-height)));
}

Learn more about CSS layouts

Building layouts can be a challenging task, especially if you don’t know the core mental model of CSS layouts. You don’t have to worry about that anymore. I released an interactive CSS layout course, and I called it The Layout Maestro.

A screenshot of the Layout Maestro course landing page

Check out The Layout Maestro course and level up your CSS layout skills.