1

As per title, I have a for-loop which cycles through an array, and creates several div boxes (four per row), each div has it's own unique vertical height. What's happening is that the second, third etc row will start where the tallest div is on the row above it. I want divs on the second, third etc row to be pushed up vertically against the div in the row above it, but that's not happening. The tallest div is blocking out the entire row, and whatever is on the next row sits below that div automatically. I want to do this through flex-box, so I thought the align-content: flex-start; command on the parent container of all the indivial div boxes would do this for me, but it's not working.

HTML:

 <div class="pasteContainerAll">

   <div class="centreLoadSpinner" v-if="pasteList.length === 0">
           <div class="lds-spinner" style="100%;height:100%;margin-auto"><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
      </div>
  </div>



 <div class="pasteContainerEach" v-else  v-for="paste in pasteList" :key="paste.id"> 
   <div class="pasteTitleContainer"><router-link :to="{ name: 'EditPaste',  params: {paste_slug: paste.slug}}"><i class="far fa-edit"></i></router-link>
   {{ paste.title }} <i class="far fa-trash-alt" @click="deletePaste(paste.slug)"></i> </div>
   <textarea-autosize readonly class="pasteContentTextarea" v-model="paste.content" v-on:click.native="copyContent(paste.content)"></textarea-autosize> 
  </div>


 </div>

CSS:

.pasteContainerAll
{
  display: flex;
  flex-wrap: wrap;
  width: 100%;
  align-content: flex-start;
}

.centreLoadSpinner
{
  display: flex;
  justify-content: center;
  width: 100%;
}

.pasteContainerEach
{
  width: 24%;
  margin-left: 0.5%;
  margin-right: 0.5%;
  margin-bottom: 1%;
  box-sizing: border-box;
}

.pasteTitleContainer
{
  margin-bottom: 4px;
  display: flex;
  width: 100%;
  font-size: 1rem;
  justify-content: space-between;
}

.pasteContentTextarea
{
  font-size: 1rem;
  width: 100%;
  resize: none;
  cursor: pointer;
  padding: 0;
  box-sizing: border-box;
  border: 0;
  font-family: 'Roboto', sans-serif;
}
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Matt Berry
  • 101
  • 1
  • 10

2 Answers2

2

Rather than thinking about trying to get rows to butt up to each other when the divs are of different heights - flip the axes and present the divs in columns using flex.

This solution nests divs of different heights inside columns, but each column is treated as part of a row. The benefit of using flex is that it will auto-space out the contents equally.

I just used odd and even styling to demonstrate the point - but it shows the masonry tile interlocking bricks that you are looking for. It just means reworking the data to present in a slightly different way.

By flipping the axes - the first div in each column creates row 1, the second div in each column creates row 2 and so on.

.wrapper {
  display: flex; 
 }
 
div {
  min-height: 50px;
  background-color: yellow;
  border: solid 1px #222;
  flex:1;
}

.column1 > div:nth-of-type(odd),
.column3 > div:nth-of-type(odd){
  height: 80px;
 }
 
 .column2 > div:nth-of-type(even),
 .column4 > div:nth-of-type(even){
  height: 80px;
 }
 
 div > div:nth-of-type(odd){background: aqua}
<div class="wrapper">
  <div class="column1">
    <div> Row 1</div>
    <div> Row 2</div>
    <div> Row 3</div>
    <div> Row 4</div>
  </div> 
  <div class="column2">
    <div> Row 1</div>
    <div> Row 2</div>
    <div> Row 3</div>
    <div> Row 4</div>
  </div>
  <div class="column3">
    <div> Row 1</div>
    <div> Row 2</div>
    <div> Row 3</div>
    <div> Row 4</div>
  </div>
    <div class="column4">
    <div> Row 1</div>
    <div> Row 2</div>
    <div> Row 3</div>
    <div> Row 4</div>
  </div>
</div>
gavgrif
  • 15,194
  • 2
  • 25
  • 27
1

If your question is asking for a masonry-style layout I don't believe its possible with flexbox alone using rows. But you can do it by adding some basic javascript.

Here's basic masonry-style code using jQuery..

$(function() {
  $('.item').each(function(index) {
    if (index > 3) { // skip first 4
      var itemAboveIndex = index - 4;
      var itemAboveDistanceToTop = $('.item:eq('+itemAboveIndex+')').offset().top;
      var itemAboveHeight = $('.item:eq('+itemAboveIndex+')').height();
      var itemAboveBottomToTop = itemAboveDistanceToTop + itemAboveHeight;
      var thisItemsTopDistanceFromTop = $(this).offset().top;
      var distanceToAboveItem = thisItemsTopDistanceFromTop - itemAboveBottomToTop;
      var marginOffset = parseInt(('-' + (distanceToAboveItem - 6) + 'px'), 10);
      $(this).css('marginTop', marginOffset);
    }
  })
});
html, body {
  margin: 0;
}
.container {
  display: flex;
  flex-wrap: wrap;
  padding: 2px;
  box-sizing: border-box;
}
.item {
  display: flex;
  width: calc(25% - 4px);
  margin: 2px;
}
.item:nth-child(1) { height: 220px; background-color: blue; }
.item:nth-child(2) { height: 200px;  background-color: green; }
.item:nth-child(3) { height: 180px; background-color: orange; }
.item:nth-child(4) { height: 240px;  background-color: red; }
.item:nth-child(5) { height: 140px;  background-color: pink; }
.item:nth-child(6) { height: 260px; background-color: yellow; }
.item:nth-child(7) { height: 210px;  background-color: black; }
.item:nth-child(8) { height: 190px; background-color: purple; }
.item:nth-child(9) { height: 170px;  background-color: grey; }
.item:nth-child(10) { height: 230px;  background-color: violet; }
.item:nth-child(11) { height: 250px; background-color: silver; }
.item:nth-child(12) { height: 120px;  background-color: gold; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

fiddle https://jsfiddle.net/Hastig/zftkg16s/

Hastig Zusammenstellen
  • 4,286
  • 3
  • 32
  • 45