Andres Andres - 6 months ago 34
CSS Question

Masonry with full-width items

I am having an issue with Masonry where if I need one element to be 100% width and the rest to be 50% width, the layout no longer puts my elements adjacent to each other. What I would like is for the items to show up side-by-side like they do when there is no 100%-width element.

Here's a js fiddle: https://jsfiddle.net/ubmf47s4/2/

<div id="boxes" class="masonry clearfix">
<div class="box box-fw" style="background: cyan;">
<div class="inner">
<p>lkaj dlksaj ldksjf lkdj flksd flkds flkds flksd jfakldsjf lkdsj flkjfd </p>
</div>
</div>
<div class="box" style="background: magenta;">
<div class="inner">
<p>lkaj dlksaj ldksjf lkdj flksd flkds flkds flksd jfakldsjf lkdsj flkjfd </p>
</div>
</div>
<div class="box" style="background: yellow;">
<div class="inner">
<p>lkaj dlksaj ldksjf lkdj flksd flkds flkds flksd jfakldsjf lkdsj flkjfd </p>
</div>
</div>
<div class="box" style="background: grey;">
<div class="inner">
<p>lkaj dlksaj ldksjf lkdj flksd flkds flkds flksd jfakldsjf lkdsj flkjfd </p>
</div>
</div>
</div>

.box{
width: 50%;
box-sizing:border-box;
}

.box-fw{
width:100%
}

$(function(){
var container = $('#boxes');

container.imagesLoaded(function(){
//console.log( "Images loaded!" );
container.masonry({
itemSelector: '.box',
isAnimated: true
});
});
});

Answer

Masonry requires a columnWidth to determine the width of the columns for it to lay out your content in, which can either be a direct pixel value or a selector for an element to measure. Since columnWidth is not specified in your code, Masonry defaults to measuring the first element in your masonry container to establish the column width. Since your first element is the one with 100% width, Masonry measures it and sets your column width to 100%, which is why your 50%-width elements no longer show up side-by-side (your entire masonry layout is effectively a single column).

More about this behavior in the Masonry docs for columnWidth.


One way to fix this is to specify an element that Masonry can measure to establish your column width - in this case I've used an element with the class column-sizer, which I've sized at 50% using CSS. Masonry then measures this element to determine the column size for layout. I borrowed the technique from David Desandro's fluid columnWidth CodePen example.

Screenshot of Result:

Result screenshot

Working Live Demo:

$(function() {
  var container = $('#boxes');

  container.imagesLoaded(function() {
    //console.log( "Images loaded!" );
    container.masonry({
      itemSelector: '.box',
      columnWidth: '.column-sizer',
      isAnimated: true
    });
  });
});
html,
body {
  margin: 0;
}
.box,
.column-sizer {
  width: 50%;
  box-sizing: border-box;
}
.box-fw {
  width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://npmcdn.com/masonry-layout@4.0.0/dist/masonry.pkgd.min.js"></script>
<script src="https://npmcdn.com/imagesloaded@4.1.0/imagesloaded.pkgd.min.js"></script>

<div id="boxes" class="masonry clearfix">
  <div class="column-sizer"></div>
  <div class="box box-fw" style="background: cyan;">
    <div class="inner">
      <p>lkaj dlksaj ldksjf lkdj flksd flkds flkds flksd jfakldsjf lkdsj flkjfd</p>
    </div>
  </div>
  <div class="box" style="background: magenta;">
    <div class="inner">
      <p>lkaj dlksaj ldksjf lkdj flksd flkds flkds flksd jfakldsjf lkdsj flkjfd</p>
    </div>
  </div>
  <div class="box" style="background: yellow;">
    <div class="inner">
      <p>lkaj dlksaj ldksjf lkdj flksd flkds flkds flksd jfakldsjf lkdsj flkjfd</p>
    </div>
  </div>
  <div class="box" style="background: grey;">
    <div class="inner">
      <p>lkaj dlksaj ldksjf lkdj flksd flkds flkds flksd jfakldsjf lkdsj flkjfd</p>
    </div>
  </div>
</div>

JSFiddle Version: https://jsfiddle.net/x9mf2c6x/