javascriptjquery-masonry

50% width on masonry elements


Currently i'm trying to apply a masonry layout to my site using Masonry.desanto

The problem if i need the first two block to size 50% of the total parent width, but i can't manage to do that using this library. The seconds element ALWAYS goes below the first one. no matter if i use some css like width: calc(50% - 100px). See an example here: https://codepen.io/josebelisario/pen/JjXvPKL

// external js: masonry.pkgd.js

$('.grid').masonry({
  itemSelector: '.grid-item',
  columnWidth: '.grid-sizer',
  percentPosition: true,
  horizontalOrder: true,
  gutter: 15
});
* { box-sizing: border-box; }

body { font-family: sans-serif; }

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

.grid {
  background: #EEE;
  max-width: 1200px;
}

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

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

.grid-sizer,
.grid-item {
  width: calc(33.33% - 30px);
}

.grid-item {
  color: white;
  height: 120px;
  float: left;
  background: #D26;
  border: 2px solid #333;
  border-color: hsla(0, 0%, 0%, 0.5);
  border-radius: 5px;
  margin-bottom: 15px;
}

.grid-item--height2 { height: 200px; }
.grid-item--height3 { height: 260px; }
.grid-item--height4 { height: 360px; }

.item-40 { width: calc(40% - 30px); }
.item-50 { width: calc(50% - 30px); }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://masonry.desandro.com/masonry.pkgd.js"></script>
<h1>Masonry - fluid columnWidth</h1>

<div class="grid">
  <div class="grid-sizer"></div>
  <div class="grid-item item-50">1</div>
  <div class="grid-item item-50">2</div>
  <div class="grid-item grid-item--height2">3</div>
  <div class="grid-item grid-item--height3">4</div>
  <div class="grid-item grid-item--height2">5</div>
  <div class="grid-item item-40">6</div>
  <div class="grid-item">7</div>
  <div class="grid-item">8</div>
  <div class="grid-item grid-item--height2">9</div>
  <div class="grid-item item-40 grid-item--height3">10</div>
  <div class="grid-item">11</div>
  <div class="grid-item grid-item--height2">12</div>
  <div class="grid-item">13</div>
  <div class="grid-item item-50 grid-item--height2">14</div>
  <div class="grid-item item-40">15</div>
  <div class="grid-item">16</div>
  <div class="grid-item grid-item--height2">17</div>
  <div class="grid-item">18</div>
  <div class="grid-item">19</div>
  <div class="grid-item grid-item--height3">20</div>
  <div class="grid-item grid-item--height2">21</div>
  <div class="grid-item">22</div>
  <div class="grid-item">23</div>
  <div class="grid-item grid-item--height2">24</div>
  <div class="grid-item">25</div>
</div>


Solution

  • For your specific example, you need to think of the lowest common denominator (think fractions) for your .grid-sizer class. (In this case, your grid looks like it is supposed to be 6 columns, of which the 50% boxes take up 3/6 and the regular .grit-item boxes take up 2/6. To be safe with width calculations in masonry grids, I never round up the % either, so your .grid-sizer width should probably read width:calc(16.66% - 15px)

    One other thing to note as well... if you want the vertical and horizontal gutter space to be even, subtract the same value in pixels from your equation (instead of 33.33% - 30px try 33.33% - 15px. That will give it that true masonry grid look.

    I've provided updated CSS for your example below. Copy and paste that into your CodePen and you should see a big improvement.

    * { box-sizing: border-box; }
    
    body { font-family: sans-serif; }
    
    /* ---- grid ---- */
    
    .grid {
      background: #EEE;
      max-width: 1200px;
    }
    
    /* clearfix */
    .grid:after {
      content: '';
      display: block;
      clear: both;
    }
    
    /* ---- grid-item ---- */
    
    .grid-sizer{
      width: calc(16.66% - 15px);
    }
    .grid-item {
      width: calc(33.33% - 15px);
    }
    
    .grid-item {
      color: white;
      height: 120px;
      float: left;
      background: #D26;
      border: 2px solid #333;
      border-color: hsla(0, 0%, 0%, 0.5);
      border-radius: 5px;
      margin-bottom: 15px;
    }
    
    .grid-item--height2 { height: 200px; }
    .grid-item--height3 { height: 260px; }
    .grid-item--height4 { height: 360px; }
    
    .item-40 { width: calc(40% - 15px); }
    .item-50 { width: calc(50% - 15px); }
    

    Let me know if this answer worked for you! :)