0

I need to arrange a bunch of blocks of fixed size into a grid. I am using flex-wrap: wrap to get as many in each row as will fit. But, I would like this whole wrapped column to be centered in the page. Ideally, I would like it to look something like this:

enter image description here

But, in the snippet I have below, the green flexbox fills to fit any space it can, so all the blue boxes are pushed all the way to the left. I don't want to set the flexbox to a fixed width because I want it to be able to flow to fit as many boxes in a row as possible, but I just don't want it to take up any more space beyond that.

Obviously, I could use justify-content: center to center the boxes within the container, but the incomplete row at the bottom gets out of alignment, which I don't want.

enter image description here

Is there any way to achieve the effect I am looking for with CSS?

I saw this question which suggested using display: inline-flex. That does seem to work when you are not wrapping, but as soon as you put on flex-wrap: wrap and add enough items to make it wrap, it jumps back to filling the full width.

.page {
  width: 100%;
  background-color: pink;
  padding: 10px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.flex-column {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  background-color: green;
  justify-content: flex-start;
  gap: 10px;
}

.flex-child {
  display: block;
  width: 200px;
  height: 100px;
  background-color: blue;
}

.button {
  display: inline-block;
  padding: 20px;
  background-color: red;
}

.
<div class='page'>
  <div class="flex-column">
    <div class="flex-child"></div>
    <div class="flex-child"></div>
    <div class="flex-child"></div>
    <div class="flex-child"></div>
    <div class="flex-child"></div>
    <div class="flex-child"></div>
    <div class="flex-child"></div>
    <div class="flex-child"></div>
  </div>
  <div class="button">Load more</div>
</div>
QuinnFreedman
  • 2,242
  • 2
  • 25
  • 42
  • The width of child is always the same? – Temani Afif Oct 30 '21 at 09:46
  • If you don't want to use fixed width on flexbox, you can use min-width:max-content, this will get rid of div's default behaviour of having 100% width and adjust its width depending on its content, but you will be forced to set it's max width too, because you are using flex wrap, so if you don't set max width, starting from the second flex child everything will be wrapped to the next row. By the way you can combine flex-direction and flex-wrap. Ex: flex-flow: row wrap; – tony Oct 30 '21 at 13:57
  • @TemaniAfif yes the children are all uniform size – QuinnFreedman Oct 30 '21 at 17:47
  • 1
    @tony worth noting that `max-content` or any of the `*-content` is an implementation that's not fully and globally supported yet. https://caniuse.com/?search=max-content – Martin Oct 30 '21 at 18:03

2 Answers2

1

Since the width is always the same, CSS grid can help you here:

.page {
  background-color: pink;
  display: grid;
  grid-template-columns:repeat(auto-fit,200px); /* same width as child */
  gap:10px; /* the same gap here */
  justify-content:center; /* center everything */
}

.flex-column {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  background-color: green;
  grid-column:1/-1; /* take all the columns */
  gap: 10px;
}

.flex-child {
  width: 200px;
  height: 100px;
  background-color: blue;
}

.button {
  padding: 20px;
  background-color: red;
  grid-column:1/-1; /* take all the columns */
  margin:auto; /* center the button */
}
<div class='page'>
  <div class="flex-column">
    <div class="flex-child"></div>
    <div class="flex-child"></div>
    <div class="flex-child"></div>
    <div class="flex-child"></div>
    <div class="flex-child"></div>
    <div class="flex-child"></div>
    <div class="flex-child"></div>
    <div class="flex-child"></div>
  </div>
  <div class="button">Load more</div>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
-3

In mine it is working like this you can see:

.page {
  width: 100%;
  background-color: pink;
  padding: 10px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.flex-column {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  background-color: green;
  justify-content: flex-start;
  gap: 10px;
  display: flex;
  padding: 20px;
}

.flex-child {
  display: block;
  width: 200px;
  height: 100px;
  background-color: blue;
  flex: 0 1 auto;
}

.button {
  display: inline-block;
  padding: 20px;
  background-color: red;
}

.
<div class='page'>
  <div class="flex-column">
    <div class="flex-child"></div>
    <div class="flex-child"></div>
    <div class="flex-child"></div>
    <div class="flex-child"></div>
    <div class="flex-child"></div>
    <div class="flex-child"></div>
    <div class="flex-child"></div>
    <div class="flex-child"></div>
  </div>
  <div class="button">Load more</div>
</div>