'Arrange images having different heights in a grid

I have to display 10 images that goes by row. For example:

1 2 3 4

5 6 7 8

9 10

(The number is the images)

With these images, I want to remove any white space between 2 images.

Currently, I am using column-count of CSS, but the images still have the gap between the rows.

How can this gap be removed ?

(P.s.: The issue is that all the images have different heights, so what happens is that the area taken by an image is dependent upon the maximum image height for that row)

I want to resolve it only using CSS without any JS.

HTML Code:

<div class="container photos-container">
  <img class="col-lg-3" src="1">
  <img class="col-lg-3" src="2">
  <img class="col-lg-3" src="3">
  <img class="col-lg-3" src="4">
  <img class="col-lg-3" src="5">
  <img class="col-lg-3" src="6">
  <img class="col-lg-3" src="7">
  <img class="col-lg-3" src="8">
  <img class="col-lg-3" src="9">
  <img class="col-lg-3" src="10">
</div>

Current result: enter image description here

Expected result: enter image description here



Solution 1:[1]

you can use masonry.js to get this

  • step 1 : link jQuery and then masonry in your page
  • step 2 : and then all you need is images with diffrant height covered by div , first give same class name to all images that you want to show in grid and apply class to parent div of those images
  • step 3 : put this code in you js file

Code :

jQuery(document).ready(function(){
    $('#here_its_id_of_parant_div').masonry({
        itemSelector: '.Image_class',
        columnWidth: 70
    });
});

example :

$( function() {

        $('#container').masonry({
            itemSelector: '.item',
            columnWidth: 70
        });

    });
body {
    font-family: sans-serif;
}

#container {
    border: 1px solid;
    padding: 5px;
}

.item {
    width: 60px;
    float: left;
    margin: 5px;
    background: #CCC;
}

.item.w2 {
    width: 130px;
}

.item.h2 {
    height: 130px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/masonry/4.2.1/masonry.pkgd.js"></script>
    <div id="container">
        <img class="item" src="https://fakeimg.pl/300/">
      <img class="item w2" src="https://fakeimg.pl/350x200/ff0000/000">
      <img class="item" src="https://fakeimg.pl/350x200/ff0000/000">
      <img class="item" src="https://fakeimg.pl/300/">
      <img class="item" src="https://fakeimg.pl/300/">
       <img class="item" src="https://fakeimg.pl/350x200/ff0000/000">
      <img class="item" src="https://fakeimg.pl/300/">
      <img class="item" src="https://fakeimg.pl/300/">
      <img class="item" src="https://fakeimg.pl/300/">
      <img class="item w2" src="https://fakeimg.pl/350x200/ff0000/000">
      <img class="item" src="https://fakeimg.pl/350x200/ff0000/000">
      <img class="item" src="https://fakeimg.pl/300/">
      <img class="item" src="https://fakeimg.pl/300/">
      <img class="item w2" src="https://fakeimg.pl/350x200/ff0000/000">
      <img class="item" src="https://fakeimg.pl/350x200/ff0000/000">
      <img class="item" src="https://fakeimg.pl/300/">
    </div>

Solution 2:[2]

You can try css-grid. Now it's widely supported by all browsers.

.container{
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-gap: 0px;
}
img{
  max-width: 100%;
}
<div class="container">
  <img src="http://www.frankieballard.com/sites/g/files/g2000005856/f/Sample-image10-highres.jpg" alt="">
  <img src="http://www.frankieballard.com/sites/g/files/g2000005856/f/Sample-image10-highres.jpg" alt="">
  <img src="http://www.frankieballard.com/sites/g/files/g2000005856/f/Sample-image10-highres.jpg" alt="">
  <img src="http://www.frankieballard.com/sites/g/files/g2000005856/f/Sample-image10-highres.jpg" alt="">
  <img src="http://www.frankieballard.com/sites/g/files/g2000005856/f/Sample-image10-highres.jpg" alt="">
  <img src="http://www.frankieballard.com/sites/g/files/g2000005856/f/Sample-image10-highres.jpg" alt="">
  <img src="http://www.frankieballard.com/sites/g/files/g2000005856/f/Sample-image10-highres.jpg" alt="">
  <img src="http://www.frankieballard.com/sites/g/files/g2000005856/f/Sample-image10-highres.jpg" alt="">
  <img src="http://www.frankieballard.com/sites/g/files/g2000005856/f/Sample-image10-highres.jpg" alt="">
  <img src="http://www.frankieballard.com/sites/g/files/g2000005856/f/Sample-image10-highres.jpg" alt="">
</div>

Edit: If you want to use images with different heights, use inline-flex

.container{
  display: inline-flex;
  flex-direction: column;
  flex-wrap: wrap;
  height: 500px;
  align-content: flex-start;
}
img{
  width: 25%;
  margin: 2px;
}
<div class="container">
  <img src="http://www.frankieballard.com/sites/g/files/g2000005856/f/Sample-image10-highres.jpg" alt="">
  <img src="https://i.pinimg.com/originals/f7/7d/27/f77d274f5d81536c67d14fb8b93d3a29.jpg" alt="">
  <img src="http://www.frankieballard.com/sites/g/files/g2000005856/f/Sample-image10-highres.jpg" alt="">
  <img src="http://www.frankieballard.com/sites/g/files/g2000005856/f/Sample-image10-highres.jpg" alt="">


  <img src="http://www.frankieballard.com/sites/g/files/g2000005856/f/Sample-image10-highres.jpg" alt="">
  <img src="http://www.frankieballard.com/sites/g/files/g2000005856/f/Sample-image10-highres.jpg" alt="">
    <img src="https://i.pinimg.com/originals/f7/7d/27/f77d274f5d81536c67d14fb8b93d3a29.jpg" alt="">
  <img src="http://www.frankieballard.com/sites/g/files/g2000005856/f/Sample-image10-highres.jpg" alt="">
  <img src="http://www.frankieballard.com/sites/g/files/g2000005856/f/Sample-image10-highres.jpg" alt="">
</div>

Solution 3:[3]

.container{
    max-width: 800px;
    width: 100%;
    margin: 0 auto;
    /* use font-size 0 to remove the 4px spacing naturally caused by display:inline-block on the children    */
    font-size: 0; 
}
.container figure{
    display: inline-block;
    max-width: 25%;
    width: 100%;
}
img{
    max-width: 100%;
}
<div class="container">
    <figure><img src="https://images.pexels.com/photos/325686/pexels-photo-325686.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt=""></figure>
    <figure><img src="https://images.pexels.com/photos/325686/pexels-photo-325686.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt=""></figure>
    <figure><img src="https://images.pexels.com/photos/325686/pexels-photo-325686.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt=""></figure>
    <figure><img src="https://images.pexels.com/photos/325686/pexels-photo-325686.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt=""></figure>
    <figure><img src="https://images.pexels.com/photos/325686/pexels-photo-325686.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt=""></figure>
    <figure><img src="https://images.pexels.com/photos/325686/pexels-photo-325686.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt=""></figure>
    <figure><img src="https://images.pexels.com/photos/325686/pexels-photo-325686.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt=""></figure>
    <figure><img src="https://images.pexels.com/photos/325686/pexels-photo-325686.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt=""></figure>
    <figure><img src="https://images.pexels.com/photos/325686/pexels-photo-325686.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt=""></figure>
    <figure><img src="https://images.pexels.com/photos/325686/pexels-photo-325686.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt=""></figure>
</div>

You need to use display:inline-block; on each image and font-size:0 on the parent to remove the spacing. Here is a sample on Codepen:

Solution 4:[4]

You can get this display using flex.

But you need to be able to give the container a definite height. (To force the wrap). And you will need 3 extra elements to act as separators to force the wrap in the correct points.

If this requirements are ok for you, then the solution is to have a flex display on the container, with direction column. And to use a order style to rearrange the items based on a 4 cycle, using nth-child:

.test {
  margin: 10px;
  width: 400px;
  border: solid 1px black;
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
  height: 400px;
  padding-bottom: -100px;
}

.elem {
  margin: 5px;
  width: 20%;
}
.elema {
  height: 130px;
}
.elemb {
  height: 80px;
}
.elemc {
  height: 40px;
}

.elem:nth-child(4n + 1) {
  order: 10;
  background-color: tomato;
}
.elem:nth-child(4n + 2) {
  order: 20;
  background-color: yellow;
}
.elem:nth-child(4n + 3) {
  order: 30;
  background-color: lightblue;
}
.elem:nth-child(4n) {
  order: 40;
  background-color: lightgreen;
}

.sep {
  background-color: red; /* only for demo purposes */
  width: 2px; /* only for demo purposes */
  height: 100%;
}
.sep:nth-last-child(3) {
  order: 15;
}
.sep:nth-last-child(2) {
  order: 25;
}
.sep:nth-last-child(1) {
  order: 35;
}
<div class="test">
    <div class="elem elema">1</div>
    <div class="elem elemb">2</div>
    <div class="elem elemc">3</div>
    <div class="elem elemb">4</div>
    <div class="elem elemc">5</div>
    <div class="elem elema">6</div>
    <div class="elem elema">7</div>
    <div class="elem elemb">8</div>
    <div class="elem elemc">9</div>
    <div class="elem elemb">10</div>
    <div class="elem elemc">11</div>
    <div class="elem elema">12</div>
    <div class="sep"></div>
    <div class="sep"></div>
    <div class="sep"></div>
</div>

Solution 5:[5]

#images-wrapper {    
   line-height: 0;       
    -webkit-column-count: 5;    
    -webkit-column-gap: 0px;    
     column-count: 5;    
     column-gap: 0px;    
}  
#images-wrapper img {    
   width: 100% !important;    
   height: auto !important;  
}  
#images-wrapper{    
   display:inline-block;    
   margin-right: auto;    
   margin-left: auto;  
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 Gangani Roshan
Solution 4 vals
Solution 5 hotProspect