3

So I have a requirement for 3 blocks of elements to look like this:

enter image description here

No vertical scrolling, only horizontal. To achieve this I thought I could make 3 div.block with the container display: flex then have my items inside each .block flex itself and wrap (note they also need to be top-bottom, left right so flex-direction: column)

But as you can see in this code (or codepen), when I do that the 3 .block's widths simply refuse to expand to their content's width, even though the .brick do wrap they overlap each other, because the .block` just stays as big as a single column.

How can I achieve this? I feel like flex is not the right tool for the containers, but I've tried display: inline-block and using a table with 3 tds which does the exact same thing.

I'm not sure how to get the .container to increase in width as more content goes in and get the .block to increase as well.

.container {
  width: 600px;
  height: 200px;
  overflow-x: auto;
  overflow-y: hidden;
  display: flex;
}

.block {
  height: 100%;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
}

.brick {
  width: 100px;
  height: 50px;
  margin: 5px;
}

.brick-red {
  background: red;
}
  
.brick-blue {
  background: blue;
}
  
.brick-orange {
  background: orange;
}
<div class="container">
  <div class="block">
    <div class="brick brick-red"></div>
    <div class="brick brick-red"></div>
    <div class="brick brick-red"></div>
    <div class="brick brick-red"></div>
    <div class="brick brick-red"></div>
    <div class="brick brick-red"></div>
    <div class="brick brick-red"></div>
  </div>
  <div class="block">
    <div class="brick brick-blue"></div>
    <div class="brick brick-blue"></div>
    <div class="brick brick-blue"></div>
    <div class="brick brick-blue"></div>
    <div class="brick brick-blue"></div>
  </div>
  <div class="block">
    <div class="brick brick-orange"></div>
    <div class="brick brick-orange"></div>
    <div class="brick brick-orange"></div>
    <div class="brick brick-orange"></div>
    <div class="brick brick-orange"></div>
  </div>
</div>
LanFeusT
  • 2,392
  • 5
  • 38
  • 53
  • it's seems an overflow issue and the item aren't expanding their width .. increase the z-index of the first one for example and you will see that red block were behind the blue – Temani Afif Aug 27 '18 at 19:37
  • Have you tried using `flex: 1` or just `flex-grow: 1` on the brick containers to have them expand? – Keno Aug 27 '18 at 19:37
  • Yeah but the problem is that I want the blocks to only take as much space as their content allows. Putting `flex: 1` will make them all take as much space as one another. – LanFeusT Aug 27 '18 at 20:04
  • 2
    https://stackoverflow.com/questions/33891709/when-flexbox-items-wrap-in-column-mode-container-does-not-grow-its-width may help – Explosion Pills Aug 27 '18 at 20:05
  • @ExplosionPills That does help thanks, it seems just not doable! – LanFeusT Aug 27 '18 at 20:32

1 Answers1

-2

You need to set the width or the flex-basis to be the total width of your content including margins, and set the flex-shrink to 0.

Try setting

.block {
  height: 100%;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  flex: 0 0 calc(110px * 3); 
  //calc can be replaced with a fixed value if you're doing a px based approach
}

.container {
  width: 400px;
  height: 200px;
  overflow-x: auto;
  overflow-y: hidden;
  display: flex;
}

.block {
  height: 100%;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  flex: 1 0 calc(110px * 3);
}

.brick {
  width: 100px;
  height: 50px;
  margin: 5px;
}

.brick-red {
  background: red;
}

.brick-blue {
  background: blue;
}

.brick-orange {
  background: orange;
}
<div class="container">
  <div class="block">
    <div class="brick brick-red"></div>
    <div class="brick brick-red"></div>
    <div class="brick brick-red"></div>
    <div class="brick brick-red"></div>
    <div class="brick brick-red"></div>
    <div class="brick brick-red"></div>
    <div class="brick brick-red"></div>
  </div>
  <div class="block">
    <div class="brick brick-blue"></div>
    <div class="brick brick-blue"></div>
    <div class="brick brick-blue"></div>
    <div class="brick brick-blue"></div>
    <div class="brick brick-blue"></div>
    <div class="brick brick-blue"></div>
    <div class="brick brick-blue"></div>
  </div>
  <div class="block">
    <div class="brick brick-orange"></div>
    <div class="brick brick-orange"></div>
    <div class="brick brick-orange"></div>
    <div class="brick brick-orange"></div>
    <div class="brick brick-orange"></div>
    <div class="brick brick-orange"></div>
    <div class="brick brick-orange"></div>
  </div>
</div>
Keno
  • 2,018
  • 1
  • 16
  • 26
  • Would the downvoters care to explain why? – Keno Aug 27 '18 at 19:52
  • Try running your changes in codepen; it does not look like his requirements – Explosion Pills Aug 27 '18 at 19:54
  • So that kind of works, but the items now have a lot of space between one another and it still overlaps if the container is smaller (say 400opx) – LanFeusT Aug 27 '18 at 19:54
  • @ExplosionPills based on the post his requirements were to simply expand the width of each block to their content using flex which I've done. Modifying the flex percentage should adjust the spacing, but I'll re-test – Keno Aug 27 '18 at 19:57
  • @LanFeusT check the updated version, it will work, given your requirements, but for a more responsive, scalable approach you might want to consider using relative units instead of absolute ones like these. – Keno Aug 27 '18 at 20:10