Search code examples
jqueryfrontendjquery-masonry

Masonry center items


I'm trying to center items inside a Masonry grid. I've read and tried quite a few of related posts about centering the grid itself but nothing worked for the items.

What I've tried so far :

  • adding / removing gutters
  • adding / removing the fitwidth option
  • tried to add a margin 0 auto on the container
  • tried to add / remove width on the container.

I've created a snippet to represent the problem

$(document).ready(function() {
  var $container = $(".grid");
  $container.masonry({
    // options
    itemSelector: '.grid-item',
    columnWidth: '.grid-sizer',
    gutter: 20,
    fitWidth: true,
  });
  $container.imagesLoaded(function() {
    $container.css({
      opacity: 0,
      visibility: "visible"
    }).animate({
      opacity: 1.0
    }, 300);
    //$container.show();
    $container.masonry('layout');
  });
});
body {
  display: flex;
  flex-direction: column;
}

.wrapper {
  width: 1260px;
  border: solid 2px red;
}

.grid {
  max-width: 1260px;
  width: 100%;
  margin: 0 auto;
  border: 1px solid #f2f2f2;
  overflow: hidden;
  padding: 0 0 2em;
  visibility: hidden;
  background: rgba(0, 255, 0, .1);
}

.grid-item,
.grid-sizer {
  display: block;
  padding: 1.5em;
  margin: 0 0 1.5em;
  background: #fff;
  width: 23%;
}
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>

<body>
  <main id="content" class="content" role="main">
    <div class="wrapper">
      <section class="grid">
        <div class="grid-sizer"></div>

        <article class="grid-item" itemtype="http://schema.org/BlogPosting" role="article">
          <p>hey there how ya doin' today ?
          </p>
        </article>

        <article class="grid-item" itemtype="http://schema.org/BlogPosting" role="article">
          <p>Hello world !</p>
        </article>

        <article class="grid-item" itemtype="http://schema.org/BlogPosting" role="article">
          <p>hey there how ya doin' today ?
          </p>
        </article>

        <article class="grid-item" itemtype="http://schema.org/BlogPosting" role="article">
          <p>Hello world !</p>
        </article>
      </section>
    </div>
  </main>
  <script src="https://code.jquery.com/jquery-3.2.1.min.js">
  </script>
  <script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js">
  </script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.imagesloaded/3.1.8/imagesloaded.pkgd.min.js">
  </script>
  <script type="text/javascript">
    $(document).ready(function() {
      var $container = $(".grid");
      $container.masonry({
        // options
        itemSelector: '.grid-item',
        columnWidth: 400,
        fitWidth: true,
      });
      $container.imagesLoaded(function() {
        $container.css({
          opacity: 0,
          visibility: "visible"
        }).animate({
          opacity: 1.0
        }, 300);
        //$container.show();
        $container.masonry('layout');
      });
    });
  </script>
</body>

As you can see, in the green section there is a small green space on the left side but there is a lot of space between the last one and the right side. How can I manage to have equal space there ? I'm pretty sure I'm missing something obvious but I can't manage to find what.


Solution

  • I finally manage to do it by removing the percentage width on the container. I've tried with the property percentPosition: true but it is incompatible with fitWidth as the doc says :

    fitWidth: true does not work with element sizing with percentage width. Either columnWidth needs to be set to a fixed size, like columnWidth: 120, or items need to have a fixed size in pixels, like width: 120px. Otherwise, the container and item widths will collapse on one another.

    Here is an example of working code :

    $(document).ready(function() {
      var $container = $(".grid");
      $container.masonry({
        // options
        itemSelector: '.grid-item',
        columnWidth: '.grid-sizer',
        gutter: 20,
        fitWidth: true,
      });
      $container.imagesLoaded(function() {
        $container.css({
          opacity: 0,
          visibility: "visible"
        }).animate({
          opacity: 1.0
        }, 300);
        //$container.show();
        $container.masonry('layout');
      });
    });
    body {
      display: flex;
      flex-direction: column;
    }
    
    .wrapper {
      width: 1260px;
      border: solid 2px red;
    }
    
    .grid {
      /*max-width: 1260px;
      width: 100%;
      */
      margin: 0 auto;
      border: 1px solid #f2f2f2;
      overflow: hidden;
      padding: 0 20px 2em;
      visibility: hidden;
      background: rgba(0, 255, 0, .1);
    }
    
    .grid-item,
    .grid-sizer {
      display: block;
      padding: 1.5em;
      margin: 0 0 1.5em;
      background: #fff;
      width: 300px;
    }
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    
    <body>
      <main id="content" class="content" role="main">
        <div class="wrapper">
          <section class="grid">
            <div class="grid-sizer"></div>
    
            <article class="grid-item" itemtype="http://schema.org/BlogPosting" role="article">
              <p>hey there how ya doin' today ?
              </p>
            </article>
    
            <article class="grid-item" itemtype="http://schema.org/BlogPosting" role="article">
              <p>Hello world !</p>
            </article>
    
            <article class="grid-item" itemtype="http://schema.org/BlogPosting" role="article">
              <p>hey there how ya doin' today ?
              </p>
            </article>
    
            <article class="grid-item" itemtype="http://schema.org/BlogPosting" role="article">
              <p>Hello world !</p>
            </article>
          </section>
        </div>
      </main>
      <script src="https://code.jquery.com/jquery-3.2.1.min.js">
      </script>
      <script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js">
      </script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.imagesloaded/3.1.8/imagesloaded.pkgd.min.js">
      </script>
      <script type="text/javascript">
        $(document).ready(function() {
          var $container = $(".grid");
          $container.masonry({
            // options
            itemSelector: '.grid-item',
            columnWidth: 400,
            fitWidth: true,
          });
          $container.imagesLoaded(function() {
            $container.css({
              opacity: 0,
              visibility: "visible"
            }).animate({
              opacity: 1.0
            }, 300);
            //$container.show();
            $container.masonry('layout');
          });
        });
      </script>
    </body>