desandro / masonry

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

Display table and margin 0 auto on grid item breaks the grid on Chrome #1046

Closed eartahhj closed 5 years ago

eartahhj commented 6 years ago

Sorry if I start from my test case instead of the asked test case, but I am working on a particular website and I found this problem and thought about posting it here in case someone might need this. I am not sure if this is a bug or just a very weird case but I spent 3 hours trying to understand the problem.

I reproduced this on Chromium 66 and Chrome 66. This does not happen on Edge and Firefox (it works fine with these browsers).

Codepen: https://codepen.io/anon/pen/aGRpbB (open it with Chrome to see one item below the other, open with Firefox or Edge to see them on 4 columns)

Problem: The grid item, in my case it was a UL LI element, with display:table and margin:0 auto; BREAKS the grid on Chrome. Solution: Apply margin:0 to the grid item (ul li in my case) What happens: it seems that for some reason, Chrome gives weird margins to the grid items and is unable to declare the correct top and left position of the items. See this screenshot: https://image.ibb.co/nyWGRJ/test_masonry.png

At the same time, it seems that disabiling the masonry init (eg. remove from the code the masonry() function) will stop the problem on Chrome. So I am not sure if it is a plugin or browser bug, but since I lost so much time trying to figure how to solve this, I hope this can help someone else with my same issue.

If you try to set the margin:0 it should solve the issue on Chrome (at least it does for me) Fix: .grid li { margin:0; float:left; width:25%; display:block; display:table; }

Test HTML:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/masonry/4.2.1/masonry.pkgd.min.js"></script>
<script src="https://unpkg.com/imagesloaded@4/imagesloaded.pkgd.min.js"></script>
<script>
$(function() {

var $grid=$(".grid").masonry({"itemSelector":".grid li","columnWidth":".grid li","percentPosition":true,"horizontalOrder":false});
$grid.imagesLoaded().progress( function() {
  $grid.masonry();
});

});
</script>
<ul class="grid">
<li class="item"><a href=""><img src="https://www.placehold.it/400x400" /><div><h3>Text</h3><p>More text</p></div></a></li>
<li class="item"><a href=""><img src="https://www.placehold.it/400x400" /><div><h3>Text</h3><p>More text</p></div></a></li>
<li class="item"><a href=""><img src="https://www.placehold.it/400x400" /><div><h3>Text</h3><p>More text</p></div></a></li>
<li class="item"><a href=""><img src="https://www.placehold.it/400x400" /><div><h3>Text</h3><p>More text</p></div></a></li>
<li class="item"><a href=""><img src="https://www.placehold.it/400x400" /><div><h3>Text</h3><p>More text</p></div></a></li>
<li class="item"><a href=""><img src="https://www.placehold.it/400x400" /><div><h3>Text</h3><p>More text</p></div></a></li>
<li class="item"><a href=""><img src="https://www.placehold.it/400x400" /><div><h3>Text</h3><p>More text</p></div></a></li>
<li class="item"><a href=""><img src="https://www.placehold.it/400x400" /><div><h3>Text</h3><p>More text</p></div></a></li>
<li class="item"><a href=""><img src="https://www.placehold.it/400x400" /><div><h3>Text</h3><p>More text</p></div></a></li>
<li class="item"><a href=""><img src="https://www.placehold.it/400x400" /><div><h3>Text</h3><p>More text</p></div></a></li>
<li class="item"><a href=""><img src="https://www.placehold.it/400x400" /><div><h3>Text</h3><p>More text</p></div></a></li>
<li class="item"><a href=""><img src="https://www.placehold.it/400x400" /><div><h3>Text</h3><p>More text</p></div></a></li>
<li class="item"><a href=""><img src="https://www.placehold.it/400x400" /><div><h3>Text</h3><p>More text</p></div></a></li>
</ul>

Test CSS

* { -webkit-box-sizing:border-box; -moz-box-sizing:border-box; box-sizing:border-box; }
*:before, *:after { -webkit-box-sizing:border-box; -moz-box-sizing:border-box; box-sizing:border-box; }
.grid { margin:0; list-style-type:none; padding:0; }
.grid li { margin:0 auto; float:left; width:25%; display:block; display:table; }
a,img { display:block; }
img { max-width:100%; border:0; }

Hope this can help, P.S. it's the first time I open an issue so I could have missed something, please be patient, I also tried to made it quickly.

desandro commented 6 years ago

Thanks for reporting this issue and for providing a test case 😁. Looks like the simplest solution is to remove display: table from the item elements, and use display: block instead.