Home > Back-end >  Shrink flexbox to the size of its children
Shrink flexbox to the size of its children

Time:10-31

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>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

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>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

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>

  • Related