Saturday, September 5, 2026
HomeCSSBalancing flex objects with flex-wrap: stability

Balancing flex objects with flex-wrap: stability


Introduction

Oftentimes, when working with flexbox and wrapping is enabled, you would possibly find yourself in a state of affairs the place the objects are wrapping, however in some unspecified time in the future, just one merchandise is wrapping (an orphan merchandise).

This usually causes net designers and builders to set off a media question to keep away from that conduct, which isn’t excellent in any respect and might break simply if the content material adjustments.

Let’s take a look at an instance to see the issue.

.checklist {
  show: flex;
  flex-wrap: wrap;
  justify-content: middle;
  hole: 0.5rem;
}

Right here is the demo:

  • Residence
  • About
  • Contact
  • Works
  • Companies
  • Talking

The final merchandise wrapped alone into a brand new line. This doesn’t really feel proper.

Flex wrap stability

Fortunately, we now have flex-wrap: stability and it’s shipped in Chrome 150. With it, the end result will look way more balanced.

Toggle flex-wrap: stability and see the way it will work simply fantastic (Chrome solely).

  • Residence
  • About
  • Contact
  • Works
  • Companies
  • Talking

Let’s take a standard instance and attempt to clear up it with out utilizing flex-wrap: stability at first as a result of flex-wrap: stability continues to be Chrome solely.

On this part now we have two major components:

  • The title
  • An inventory of social media icons

Have a look:

Buffer section

From the primary look, it seems to be okay. Nonetheless, upon resizing the viewport, the format begins to interrupt. See the video under:

The icon’s wrapper is a flexbox container, which is utilizing justify-content: space-between. That is what’s inflicting the icons to wrap, after which having two icons in a line at a far distance from one another.

I don’t suppose that is intentional.

Buffer section

Let’s repair it. I replicated the part within the demo under so we are able to test find out how to clear up that format downside.

Answer 1: Container queries

First, I set the flex container to wrap usually and used justify-content: middle to middle the icons.

.channels {
  show: flex;
  flex-wrap: wrap;
  justify-content: middle;
}

Join your favourite accounts

I assumed in regards to the following:

  • Outline a container for the channels.
  • Calculate the width of every social channel plus the hole in between.
  • If the container width is lower than or equal the calculated channels width, we’ll pressure the format to wrap.

This answer ought to work in any browser that helps container queries. The concept is to set the max-width on small container sizes to indicate a pre-defined variety of channels per row, I set it to five.

.section-wrapper {
  container-type: inline-size;
  container-name: demo;
}

.part {
  --size: 44px;
  --gap: 1rem;
  --count: 8;
  --width: calc(var(--size) * var(--count) + var(--gap) * (var(--count) - 1));
  --items-row: 5;
  --max-width: calc(
      var(--size) * var(--items-row) + var(--gap) * (var(--items-row) - 1)
    );
}

.channels {
  max-width: var(--max-width);

  
  @container (width >= 464px) {
    max-width: preliminary;
    background-color: rgba(from deeppink r g b / 0.3);
  }
}

Resize the vary slider, or the container, and see how the format adjustments.

Join your favourite accounts

Answer 2: utilizing max-width with a conditional clamp

On this answer, I outlined a container on the father or mother ingredient, then used max-width to deal with the format.

.section-wrapper {
  container-type: inline-size;
  container-name: demo;
}

.part {
  --size: 44px;
  --gap: 1rem;
  --count: 8;
  --items-row: 5;
  --width: calc(var(--size) * var(--count) + var(--gap) * (var(--count) - 1));
  --min: calc(
    var(--size) * var(--items-row) + var(--gap) * (var(--items-row) - 1)
  );
  --max-width: clamp(var(--min), (100cqw - var(--width)) * 999, 100%);

  .channels {
    max-width: var(--max-width);
  }
}

We’ve got to know the next upfront:

  • Measurement of the social channel (44px)
  • Hole
  • Whole depend
  • Variety of objects to indicate per row

From these, we are able to calculate the minimal variety of objects to indicate per row, and the utmost width.

Right here is the working demo:

Join your favourite accounts

If you happen to’re questioning, this answer is utilizing a conditional clamp, I wrote about it on my weblog earlier than right here.

Answer 3: show contents

On this answer, I divided the objects into two teams. On smaller sizes, the teams are flattened with show: contents. On bigger sizes, the teams are seen to imitate the balanced wrapping conduct.

<div class="channels">
  <div class="group-1">
    
  </div>
  <div class="group-2">
    
  </div>
</div>
.channels {
  show: flex;
  flex-wrap: wrap;
  justify-content: middle;
  hole: 1rem;

  > div {
    
    show: contents;

    @container (width >= 500px) {
      show: inherit;
      flex-wrap: inherit;
      justify-content: inherit;
      hole: inherit;
      background-color: rgba(from deeppink r g b / 0.3);
    }
  }
}

Join your favourite accounts

Whereas this works, it’s not my favourite answer, but it surely’s significantly better than simply utilizing justify-content: space-between.

I’ve an article about show: contents, if you wish to study extra about it.

Answer 4: A flex merchandise in between

This answer didn’t work nicely, however I wish to present it anyway. The concept is that we add a pseudo ingredient and use the order property.

The concept is to pressure the pseudo ingredient to take the total area, and to put it in the midst of the checklist by utilizing --count property.

ul {
  &:earlier than {
    content material: "";
    order: calc(var(--count) / 2 + 1);
    flex: 0 0 100%;
  }
}

li {
  &:nth-child(1) {
    order: 1;
  }
  
}

Join your favourite accounts

Answer 5: Flex wrap stability

After all of the above options, I’ll present you the way straightforward it’s to simply use flex-wrap: stability.

.channels {
  show: flex;
  flex-wrap: stability;
  justify-content: middle;
  hole: 1rem;
}

Join your favourite accounts

That’s it!

Flex line depend

Whereas researching about flex-wrap: stability, I found that there’s a new CSS property, which is flex-line-count.

This property allow us to set a minimal variety of traces for the wrapped flex objects. Even when the area is sufficient and the objects usually are not wrapping, we are able to pressure a minimal variety of traces for wrapping.

.checklist {
  show: flex;
  flex-wrap: stability;
  flex-line-count: 2;
  hole: 0.5rem;
}

I compelled the flex wrapping to begin from no less than two traces, even when the area is sufficiently big for the objects to remain in a single line.

  • Residence
  • About
  • Contact
  • Works
  • Companies
  • Talking

This looks like magic, and I imagine it’s going to open up a brand new world of use circumstances that weren’t doable earlier than. How can we profit from this?

Right here is an instance the place now we have a header and we wish the navigation to at all times wrap into two traces. Usually, we’d prohibit the navigation by:

  • Setting a most width.
  • Defining a grid with a set width for the navigation.
  • and extra…

Within the following demo, I used the traditional max-width answer, have a look:

.nav ul {
  max-width: 320px;
  margin-inline: auto;
  show: flex;
  justify-content: middle;
  flex-wrap: wrap;
  hole: 0.5rem;
}

Whereas this works, we misplaced the power to type the navigation wrapper. For instance, if we wish to add a background shade, it will likely be restricted to the max-width.

With flex-line-count, we are able to outline the minimal variety of traces for the wrapped flex objects, and the navigation wrapper width will keep as is.

.nav ul {
  show: flex;
  justify-content: middle;
  flex-wrap: stability;
  flex-line-count: 2;
  hole: 0.5rem;
}

Masonry format with flex-line-count

Can we do a masonry format with flex-line-count? The brief reply is sure, let’s discover out.

First, I’ll use a easy instance to check the concept, then transfer to at least one with actual content material.

.format {
  show: flex;
  flex-direction: column;
  flex-wrap: stability;
  flex-line-count: 4;
  hole: 1.5rem;
}

Quick, intense, and served in a small cup.

A kettle, a filter, and a little bit of endurance.

Steep coarse grounds in chilly water in a single day, then pressure. The result’s easy, low-acid, and straightforward to maintain within the fridge for a number of days.

Stovetop traditional, prepared earlier than the toast pops.

Coarse grind, 4 minutes, then plunge. Full-bodied and somewhat silty, which is both a characteristic or a bug relying on who you ask.

Small, mild, and arduous to get fallacious.

Equal elements espresso and steamed milk.

Finely floor beans, water, and sugar go into the cezve collectively. Served unfiltered, with the sediment settling on the backside whilst you drink.

From the primary look, it seems to be good. Nonetheless, when resized, the variety of columns will keep the identical, which is able to trigger the objects to look very small.

The best way to repair that? I assumed in regards to the following:

  • Assign a container to the format.
  • Outline the cardboard width.
  • Divide the container width by the cardboard width to get the variety of columns.
  • Use spherical() operate to get the closest integer.
.format {
  --line-min: 190px;
  --line-count: clamp(1, spherical(down, 100cqw / var(--line-min)), 4);
  show: flex;
  flex-direction: column;
  flex-wrap: stability;
  flex-line-count: var(--line-count);
  hole: 1.5rem;
}

Try the demo under:

Espresso

Espresso

Quick, intense, and served in a small cup.

Cold brew

Chilly brew

Steep coarse grounds in chilly water in a single day, then pressure. The result’s easy, low-acid, and straightforward to maintain within the fridge for a number of days.

French press

French press

Coarse grind, 4 minutes, then plunge. Full-bodied and somewhat silty, which is both a characteristic or a bug relying on who you ask.

Cortado

Cortado

Equal elements espresso and steamed milk.

This demo is simply an experiment, and I wish to point out that the studying order isn’t the identical because the visible order, however no less than, I took the flex-line-count to its full potential right here (hopefully).

Outro

Flex wrap balancing is a good new characteristic that I sit up for utilizing extra. Truthfully, I didn’t count on to get pleasure from utilizing the flex-line-count property! I sit up for seeing what you give you.

Thanks for studying!

Be taught extra about CSS layouts

Constructing layouts generally is a difficult process, specifically when you don’t know the core psychological mannequin of CSS layouts. You don’t have to fret about that anymore. I launched an interactive CSS format course, and I referred to as it, The Format Maestro.

A screenshot of the Layout Maestro course landing page

Checkout The Format Maestro course and stage up your CSS format expertise.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments