desandro / masonry

:love_hotel: Cascading grid layout plugin
https://masonry.desandro.com
16.44k stars 2.11k forks source link

Overlapping Images - Bootstrap User #1147

Open mattcanty opened 3 years ago

mattcanty commented 3 years ago

Test case: https://codepen.io/matthewcanty/pen/NWbEQOj (you may not see the issue, so I provide screenshot as well 😄 )

image

Hi, I've been building a website to showcase photography. I used Bootstrap and followed the basic Masonry advice:

etc
<div class="row grid" data-masonry='{"percentPosition": true }'>
etc

I realise that it's likely due to the image size. But as my JS is minimal (all I did was add the data-masonry attribute) I'm not sure now how to fix. I have put a hack in, and it is working.

setTimeout(function () {
  var msnry = new Masonry('.grid');
  msnry.layout();
}, 100);

setTimeout(function () {
  var msnry = new Masonry('.grid');
  msnry.layout();
}, 300);

setTimeout(function () {
  var msnry = new Masonry('.grid');
  msnry.layout();
}, 1000);

setTimeout(function () {
  var msnry = new Masonry('.grid');
  msnry.layout();
}, 5000);

The theory is that most will download all the images fairly quickly, especially if cached. Thereforethe 100/300ms take care of those to give a "rapid" feel. For everyone else I through in a 1000 & 5000 for good measure.

Obviously I don't like this, but I will keep it until I have dealt with other issues!

rslhdyt commented 3 years ago

same issue with bootstrap 5

hamransp commented 3 years ago

Yes, Masonry overlapping item images in bootstrap 5

tang2087 commented 3 years ago

I faced the same issue as images loading is not completed when the layout is refreshed

melihcoban commented 3 years ago

I am facing the same issue with the Bootstrap 5. Applying the mattcanty's hotfix fixes the issue.

mattcanty commented 3 years ago

More of a hack than a fix but I’m glad it alleviates the issue right now.

On Tue, 14 Sep 2021 at 16:14, Melih Çoban @.***> wrote:

I am facing the same issue with the Bootstrap 5. Applying the mattcanty's hotfix fixes the issue.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/desandro/masonry/issues/1147#issuecomment-919248082, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAP6E3KASE7QMWUTN4HAANLUB5RETANCNFSM4Y6RCSLQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

tang2087 commented 3 years ago

I have adopted mattcanty’s fix and also added another approach of adding event listener on image load: Masonry layout You could also use Promise to call layout once all images are loaded. However user experience might not be great as users can view the significant transition from overlapping to a neat layout.

thexzan commented 3 years ago

This is the way i solve it, it wait until all images is loaded and then trigger the Masonry it may not have the best UX but it work.


Promise.all(Array.from(document.images).filter(img => !img.complete).map(img => new Promise(resolve => { img.onload = img.onerror = resolve; }))).then(() => {
    var msnry = new Masonry('.grid');
    msnry.layout();
});
tang2087 commented 3 years ago

This is the way i solve it, it wait until all images is loaded and then trigger the Masonry it may not have the best UX but it work.

Promise.all(Array.from(document.images).filter(img => !img.complete).map(img => new Promise(resolve => { img.onload = img.onerror = resolve; }))).then(() => {
  var msnry = new Masonry('.grid');
  msnry.layout();
});

Yes I used the same approach and shared it in my website too. :)

TixMartin commented 2 years ago

Try with imagesLoaded. First load imagesLoaded.js and masonry.js, and then place the following script at the bottom.

<script type="text/javascript">

 var $grid = $('#masonry').masonry({
   itemSelector: '.col',
   percentPosition: true
 });

 // layout Masonry after each image loads
 $grid.imagesLoaded().progress( function() {
   $grid.masonry();
 });

</script>

Sample HTML:

<div id="masonry" class="row row-cols-2 row-cols-sm-3 row-cols-md-4 row-cols-lg-5 g-3 " >
    <div class="col">
               some image
    </div>
        <div class="col">
               some image
    </div>
    <div class="col">
               some image
    </div>
    <div class="col">
               some image
    </div>
</div>
taimoor-shan commented 1 year ago

@mattcanty Resolved. just "replace" async with "sync" in CDN link.

dreamersofdreams commented 1 year ago

tried a lot of various solutions offered on masonry site, but only thing that worked for me on Bootstrap 5 was using @mattcanty hack above... hopefully this will eventually be addressed