Search code examples
javascripthtmljquerycssjquery-isotope

How to get the images to be the same size using Isotope JS


I am using Isotope JS and I am trying to get an evenly spaced, proportional gallery layout but I am not sure what is wrong. My code isn't cooperating with isotope. I would be very grateful if someone could help me figure out what I am doing wrong.

I created a codepen if that would help as well: https://codepen.io/jaytb95/pen/vYxMGqP

$(document).ready(function() {
    $grid = $('.grid').isotope({
        filter: '*',
        itemSelector: '.grid-item',
        layoutMode: 'fitRows',
        percentPosition: true
    });
    $filters = $('.list');
    
    $filters.click(function() {
        $value = $(this).attr('data-filter');
        if ($value == 'all') {
            $grid.isotope({ filter: '*' });
        } else {
          $grid.isotope({ filter: '.' + $value });  
        }
        
    });
});
ul {
            display: flex;
            list-style: none;
            justify-content: center;
            margin-top: 25px;
        }

        ul > li {
            margin-left: 15px;
            cursor: pointer;
            padding: 0.5rem 1rem;
            background-color: crimson;
            color: white;
            font-family: 'Calibri',sans-serif;
        }

.container {
    max-width: 90%;
    margin: 0 auto;
}

.grid {
    columns: 4 25vh;
}

.grid-item img {
    object-fit: cover;
    width: 100%;
    height: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/isotope.pkgd.min.js"></script>

<ul>
    <li class="list" data-filter="all">All</li>
    <li class="list" data-filter="phone">Phone</li>
    <li class="list" data-filter="camera">Camera</li>
    <li class="list" data-filter="watch">Watch</li>
</ul>
<div class="container">
    <div class="grid">
        <div class="grid-item phone">
            <img src="https://picsum.photos/500/300" alt="" />
        </div>
        <div class="grid-item camera">
            <img src="https://picsum.photos/400/200" alt="" />
        </div>
        <div class="grid-item watch">
            <img src="https://picsum.photos/500/300" alt="" />
        </div>
        <div class="grid-item camera">
            <img src="https://picsum.photos/400/200" alt="" />
        </div>
        <div class="grid-item watch">
            <img src="https://picsum.photos/500/300" alt="" />
        </div>
        <div class="grid-item camera">
            <img src="https://picsum.photos/400/200" alt="" />
        </div>
        <div class="grid-item watch">
            <img src="https://picsum.photos/500/300" alt="" />
        </div>
    </div>
</div>


Solution

  • You should initialize Isotope after all the images have loaded. This means that you also have to include the imagesLoaded library in your code.

    Also, to make the images proportional and evenly spaced, set the width of each .grid-item class to 50%, set the width of each image to calc(100% - 0.25rem), and change the layout mode to masonry. Your "image gallery" should work just fine after this:

    $(document).ready(function() {
      $grid = $(".grid").imagesLoaded(function() {
        $grid.isotope({
          filter: "*",
          itemSelector: ".grid-item",
          layoutMode: "masonry",
          percentPosition: true
        });
      });
    
      $filters = $(".list");
      $filters.click(function() {
        $value = $(this).attr("data-filter");
        if ($value == "all") {
          $grid.imagesLoaded(function() {
            $grid.isotope({ filter: "*" });
          });
        } else {
          $grid.imagesLoaded(function() {
            $grid.isotope({ filter: "." + $value });
          });
        }
      });
    });
    ul {
      display: flex;
      list-style: none;
      justify-content: center;
      margin-top: 25px;
    }
    
    ul > li {
      margin-left: 15px;
      cursor: pointer;
      padding: 0.5rem 1rem;
      background-color: #dc143c; /* crimson */
      color: #fff; /* white */
      font-family: "Calibri", sans-serif;
    }
    
    .container {
      max-width: 90%;
      margin: 0 auto;
    }
    
    .grid {
      columns: 4 25vw;
    }
    
    .grid-item {
      width: 50%;
    }
    
    .grid-item img {
      object-fit: cover;
      -o-object-fit: cover;
      width: calc(100% - 0.25rem);
      height: auto;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/isotope.pkgd.min.js"></script>
    <script src="https://unpkg.com/[email protected]/imagesloaded.pkgd.min.js"></script>
    
    <ul>
      <li class="list" data-filter="all">All</li>
      <li class="list" data-filter="phone">Phone</li>
      <li class="list" data-filter="camera">Camera</li>
      <li class="list" data-filter="watch">Watch</li>
    </ul>
    <div class="container">
      <div class="grid">
        <div class="grid-item phone">
          <img src="https://picsum.photos/500/300" alt="">
        </div>
        <div class="grid-item camera">
          <img src="https://picsum.photos/400/200" alt="">
        </div>
        <div class="grid-item watch">
          <img src="https://picsum.photos/500/300" alt="">
        </div>
        <div class="grid-item camera">
          <img src="https://picsum.photos/400/200" alt="">
        </div>
        <div class="grid-item watch">
          <img src="https://picsum.photos/500/300" alt="">
        </div>
        <div class="grid-item camera">
          <img src="https://picsum.photos/400/200" alt="">
        </div>
        <div class="grid-item watch">
          <img src="https://picsum.photos/500/300" alt="">
        </div>
      </div>
    </div>