Search code examples
htmlcssjquery-isotopejquery-masonrypackery

responsive Masonry/Packary overlaps over other images and DOM elements


I have been working on several things related to this for hours now. I finally got it to work, but somehow it broke again. So here I am.

For my use-case I want to display images with Packery. The images have to sort themselves so that the grid has no gaps. The user will be able to choose the sizing of the images inside the grid, and the grid should sort accordingly.

With every method that I've tried, they display over the rest of the page, or stack on top of each other.

I tested this with Masonry, Packery and Isotope. All give the same results. My code sample below is of the Packery attempt.

Edit: After more testing, I figured out that this issue only occurs when combining height and width classes. When only one of those is present, no overlapping occurs. I do need this functionality though.

overlap over DOM element

overlap over other images in grid

The blue line shows where the images should end.

$(document).ready(function() {
  let $grid = $('.grid').imagesLoaded(function() {
    // init Packery after all images have loaded
    $('.grid').packery({
      itemSelector: '.grid-item',
      percentPosition: true
    });
    $grid.packery('layout');
  });

  // I have also tried this approach
  let $grid = $('.grid').packery({
    itemSelector: '.grid-item',
    percentPosition: true
  });
  // layout Packery after each image loads
  $grid.imagesLoaded().progress(function() {
    $grid.packery();
  });
});
* {
  box-sizing: border-box;
}


/* force scrollbar, prevents initial gap */

html {
  overflow-y: scroll;
}

body {
  font-family: sans-serif;
}


/* ---- grid ---- */

.grid {
  background: #DDD;
}


/* clear fix */

.grid:after {
  content: '';
  display: block;
  clear: both;
}


/* ---- .element-item ---- */


/* 5 columns, percentage width */

.grid-item {
  float: left;
  width: 16.667%;
  height: 200px;
}

.grid-item img {
  display: block;
  width: 100%;
  height: 100%;
}

.grid-item--small-width {
  width: 16.667%;
}


/*Small*/

.grid-item--double-small-width {
  width: 33.334%;
}


/*Double*/

.grid-item--half-width {
  width: 50%;
}


/*Half*/

.grid-item--three-fourth-width {
  width: 66.668%;
}


/*Bit More Than Half*/

.grid-item--big-width {
  width: 83.335%;
}


/*Big*/

.grid-item--full-width {
  width: 100%;
}


/*Full*/

.grid-item--small-height {
  height: 16.667%;
}


/*Small*/

.grid-item--double-small-height {
  height: 33.334%;
}


/*Double*/

.grid-item--half-height {
  height: 50%;
}


/*Half*/

.grid-item--three-fourth-height {
  height: 66.668%;
}


/*Bit More Than Half*/

.grid-item--big-height {
  height: 83.335%;
}


/*Big*/

.grid-item--full-height {
  height: 100%;
}


/*Full*/
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="css/masonry.classes.css">

<section>
  <div class="container-fluid text-center" style="background-color: white; color: black">
    <div class="container" style="margin-bottom: 20px">
      <div class="row">
        <h1>Portfolio</h1>
        <div class="col-md-12">
          <div class="grid" style="height: 1200px;">
            <div class="grid-sizer"></div>
            <div class="grid-item grid-item--small-width grid-item--full-height"><img class="img-responsive" src="http://landstededev.test/storage/projects/projectImage_4.png"></div>
            <div class="grid-item grid-item--small-width grid-item--half-height"><img class="img-responsive" src="http://landstededev.test/storage/projects/projectImage_4.png"></div>
            <div class="grid-item grid-item--small-width grid-item--small-height"><img class="img-responsive" src="http://landstededev.test/storage/projects/projectImage_4.png"></div>
            <div class="grid-item grid-item--small-width grid-item--small-height"><img class="img-responsive" src="http://landstededev.test/storage/project/projectImage_4.png"></div>
            <div class="grid-item grid-item--full-width grid-item--small-height"><img class="img-responsive" src="http://landstededev.test/storage/projects/projectImage_4.png"></div>
            <div class="grid-item grid-item--small-width grid-item--small-height"><img class="img-responsive" src="http://landstededev.test/storage/projects/projectImage_4.png"></div>
            <div class="grid-item grid-item--small-width grid-item--small-height"><img class="img-responsive" src="http://landstededev.test/storage/projects/projectImage_4.png"></div>
            <div class="grid-item grid-item--small-width grid-item--small-height"><img class="img-responsive" src="http://landstededev.test/storage/projects/projectImage_4.png"></div>
            <div class="grid-item grid-item--small-width grid-item--small-height"><img class="img-responsive" src="http://landstededev.test/storage/projects/projectImage_4.png"></div>
            <div class="grid-item grid-item--small-width grid-item--small-height"><img class="img-responsive" src="http://landstededev.test/storage/projects/projectImage_4.png"></div>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>

<section>
  <div class="container-fluid" style="background-color: #f0f0f0; color: #121212">
    <div class="container">
      <div class="row align-items-center justify-content-center">
        <div class="col-4 text-center">
          <a href="https://twitter.com/" class="btn btn-primary" style="margin: 5px; width: 100%">Link To Twitter</a>
          <br>
        </div>
        <div class="col-8" style="border-left: 2px solid #121212">
          <h2 class="title">Title</h2>
          <p>Some description will go here</p>
        </div>
      </div>
    </div>
  </div>
</section>

<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="https://unpkg.com/[email protected]/dist/packery.pkgd.min.js"></script>
<script src="https://unpkg.com/imagesloaded@4/imagesloaded.pkgd.min.js"></script>

The javascript does not work with or without the $grid.packery('layout'); part. I have this here because it fixed an issue I had before.


Solution

  • After experimenting for a few more hours, I figured out that it is not possible to combine width and height classes that both use percentages. I now use percentages for width only. Height now uses fixed px values.