skip to Main Content

For example, I have 5 photos which I want to place into 3 columns – this means that we have 3×2 grid. 3 items are in the first row, 2 items in the second row. After this positioning, I have one cell empty left. I want to adjust items per center that there no empty space in the right left.

Things to mention:

  • Columns are adjustable and entered by user, so it’s should be dynamic and don’t work specifically with 3
  • For instance, if I have 6 photos, there would be all places filled which is ok
  • I already found some solutions on SO, but those solutions were for one specific case which I can’t adapt for my problem

Here is the code:

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 20px;
}
<div class="grid">
  <div class="col">
    <img style="width: 100%;height: 100%" loading="lazy" width="100" height="100" class="gallery__img" src="https://cpmr-islands.org/wp-content/uploads/sites/4/2019/07/test.png">
  </div>
  <div class="col">
    <img style="width: 100%;height: 100%" loading="lazy" width="100" height="100" class="gallery__img" src="https://cpmr-islands.org/wp-content/uploads/sites/4/2019/07/test.png">
  </div>
  <div class="col">
    <img style="width: 100%;height: 100%" loading="lazy" width="100" height="100" class="gallery__img" src="https://cpmr-islands.org/wp-content/uploads/sites/4/2019/07/test.png">
  </div>
  <div class="col">
    <img style="width: 100%;height: 100%" loading="lazy" width="100" height="100" class="gallery__img" src="https://cpmr-islands.org/wp-content/uploads/sites/4/2019/07/test.png">
  </div>
  <div class="col">
    <img style="width: 100%;height: 100%" loading="lazy" width="100" height="100" class="gallery__img" src="https://cpmr-islands.org/wp-content/uploads/sites/4/2019/07/test.png">
  </div>
</div>

My desired solution with 3 columns and all spaces filled:
enter image description here

3 columns and one space left:
enter image description here

3

Answers


  1. Pure CSS and without javascript you would need to use some sort of pseudo selector approach to target the orphan image

    *,
    *:before,
    *:after {
      box-sizing: border-box;
    }
    
    :root {
      --main-bg-color: pink;
    }
    
    body {
      height: 100vh;
      background: #87480f;
      background: linear-gradient(135deg, #c26f25 0%, #87480f 100%);
      display: flex;
      flex-direction: column;
      margin: 20px;
    }
    
    .container {
      display: grid;
      height: 100%;
      align-items: start;
      gap: 20px;
      grid-template-columns: repeat(auto-fill, minmax(100%, 1fr));
      grid-auto-rows: max-content;
    }
    
    .grid-item {
      position: relative;
    }
    
    .grid-item:last-child {
      grid-column: auto;
    }
    
    img {
      aspect-ratio: 16 / 9;
      object-fit: cover;
      width: 100%;
      border-radius: 10px;
      box-shadow: 3px 3px 5px rgba(69, 47, 27, 0.8);
    }
    
    .grid-item:before {
      content: "";
      position: absolute;
      top: -1.5px;
      left: -1.5px;
      width: 100%;
      height: 100%;
      border-radius: 16px;
      z-index: -1;;
      background-color: rgba(247, 231, 215, 0.25);
      box-shadow: -3px -3px 4px rgba(255, 255, 255, 0.2);
    }
    
    @media (min-width: 576px) {
      .container {
        --img-width: calc((100% - 40px) / 2);
        grid-template-columns: repeat(auto-fill, minmax(var(--img-width), 1fr));
      }
    
      .grid-item:last-child {
        grid-column: span 2;
      }
    
    }
    
    @media (min-width: 768px) {
      .container {
        --img-width: calc((100% - 40px) / 3);
        grid-template-columns: repeat(auto-fill, minmax(var(--img-width), 1fr));
      }
    
      .grid-item:last-child {
        grid-column: span 3;
      }
    }
    <!doctype html>
    
    <html>
      <head>
        <link rel="stylesheet" href="lib/style.css">
        <script src="lib/script.js"></script>
      </head>
    
      <body>
        <div class="container">
          <div class="grid-item">
            <img src='https://unsplash.it/1024/683?image=102';/>
          </div>
          <div class="grid-item">
            <img src='https://unsplash.it/1024/683?image=110';/>
          </div>
          <div class="grid-item">
            <img src='https://unsplash.it/1024/683?image=112';/>
          </div>
          <div class="grid-item">
            <img src='https://unsplash.it/1024/683?image=132';/>
          </div>
          <div class="grid-item">
            <img src='https://unsplash.it/1024/683?image=35';/>
          </div>
          <div class="grid-item">
            <img src='https://unsplash.it/1024/683?image=289';/>
          </div>
          <div class="grid-item">
            <img src='https://unsplash.it/1024/683?image=184';/>
          </div>
        </div>
      </body>
    </html>
    Login or Signup to reply.
  2. You can use display: flex instead of display: grid, and have a fixed width for the divs inside the container, so that when it contains more than 3 divs in a row, it wraps to the next column.

    * {
      margin: 0;
      padding: 0;
    }
    
    .container {
      width: 100vw;
      height: 100vh;
      display: flex;
      align-items: center;
      justify-content: center;
      flex-wrap: wrap;
    }
    
    .col {
      max-width: 33%;
    }
    <div class="container">
        <div class="col">
          <img style="width: 100%;height: 100%" loading="lazy" width="100" height="100" class="gallery__img" src="https://cpmr-islands.org/wp-content/uploads/sites/4/2019/07/test.png">
        </div>
        <div class="col">
          <img style="width: 100%;height: 100%" loading="lazy" width="100" height="100" class="gallery__img" src="https://cpmr-islands.org/wp-content/uploads/sites/4/2019/07/test.png">
        </div>
        <div class="col">
          <img style="width: 100%;height: 100%" loading="lazy" width="100" height="100" class="gallery__img" src="https://cpmr-islands.org/wp-content/uploads/sites/4/2019/07/test.png">
        </div>
        <div class="col">
          <img style="width: 100%;height: 100%" loading="lazy" width="100" height="100" class="gallery__img" src="https://cpmr-islands.org/wp-content/uploads/sites/4/2019/07/test.png">
        </div>
        <div class="col">
          <img style="width: 100%;height: 100%" loading="lazy" width="100" height="100" class="gallery__img" src="https://cpmr-islands.org/wp-content/uploads/sites/4/2019/07/test.png">
        </div>
    </div>
    Login or Signup to reply.
  3. Here’s the solution using flex as requested. You can change number of columns through the input fild.

    Notes:

    • You can set a gap with max 1%, otherwise, the gap may make the content to wrap for the next line. If you want to set a higher gap, make account for it in your width value in the javascript, try using calc .e.g. width = "calc( 33% - 10px)" where 10px is your gap value.

    • The added css max-height and max-width for styling images is just to make sure the images don’t get too big for small number of colums .e.g. 1 or 2 as width for most devices are bigger than height. Having .col div with height equal to the width when the width is 100% of the viewport, will make the image too big for the screen, you can remove them or adjust them as you like, but if you want them circular, make sure both max-height and max-width have the same values.

      .img-style {
      height: 100%;
      width: 100%;

      max-height: 400px;
      max-width: 400px;
      

      }

    • The flex display for .col class is just to center the image inside the div.
    document.querySelector(".input-group").addEventListener("submit", changeNumOfCols);
    
    function changeNumOfCols(event) {
      event.preventDefault();
    
      const nums = document.querySelector("#cols_input").value;
      const cols = document.querySelectorAll('.col');
    
      cols.forEach((col) => {
        console.log(col);
        col.style.width = parseInt((100 / nums) - 1) + '%';
      });
    }
    .grid {
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
      gap: 1%;
    }
    
    .col {
      width: 32%;
      margin: 0;
      padding: 0;
      
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    .input-group {
      margin: 1rem;
      display: flex;
      justify-content: center;
    }
    
    .img-style {
      height: 100%;
      width: 100%;
      
      max-height: 400px;
      max-width: 400px;
    }
    <form class="input-group">
      <input id="cols_input" type="number" placeholder="number of columns" />
      <input type="submit" value="submit">
    </form>
    <div class="grid">
      <div class="col">
        <img class="img-style" loading="lazy" width="100" height="100" class="gallery__img" src="https://cpmr-islands.org/wp-content/uploads/sites/4/2019/07/test.png">
      </div>
      <div class="col">
        <img class="img-style" loading="lazy" width="100" height="100" class="gallery__img" src="https://cpmr-islands.org/wp-content/uploads/sites/4/2019/07/test.png">
      </div>
      <div class="col">
        <img class="img-style" loading="lazy" width="100" height="100" class="gallery__img" src="https://cpmr-islands.org/wp-content/uploads/sites/4/2019/07/test.png">
      </div>
      <div class="col">
        <img class="img-style" loading="lazy" width="100" height="100" class="gallery__img" src="https://cpmr-islands.org/wp-content/uploads/sites/4/2019/07/test.png">
      </div>
      <div class="col">
        <img class="img-style" loading="lazy" width="100" height="100" class="gallery__img" src="https://cpmr-islands.org/wp-content/uploads/sites/4/2019/07/test.png">
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search