4

Question: CODEPEN

How can I design a grid using CSS Grid to make a Carousel that's grid items are responsive to a fixed number of grid columns which will vary per breakpoint?

enter image description here

PROBLEM: The grid-items don't scale as expected on responsive breakpoints. The grid-items peak out not to spec.

Please checkout a video of how I want grid-items to scale per breakpoint: https://i.stack.imgur.com/3wBqM.jpg

Background

I asked a previous question about how I can make grid-items flow horizontally using css grid:

Grid CSS container that scrolls horizontally when children use grid-column?

In the end I got code that worked for desktop but not for any other breakpoints:

CSS:

.section {
  width: 100%;
  display: block;
  background: red;
  box-sizing: border-box;
  padding: 40px 24px;

  @media screen and (min-width: 600px) and (max-width: 1139px) {
    background: orange;
    padding: 56px 48px;
  }

  @media screen and (min-width: 1140px) {
    padding: 64px 48px;
    background: green;
  }
}

.container {
  margin: 0 auto;
  background: rgba(244,244,244, .25);
  max-width: 599px;


  @media screen and (min-width: 600px) and (max-width: 1139px) {
    max-width: 1039px;
    background: rgba(244,244,244, .25);
  }

  @media screen and (min-width: 1140px) {
    max-width: 1032px;
    background: rgba(244,244,244, .25);
  }
}

.samba-grid {
  display: grid;
  background: inherit;
  width: 100%;
  overflow-x: auto;
  overflow-y: hidden;

  grid-auto-columns: minmax(55px, 1fr);
  grid-gap: 24px;

  @media screen and (min-width: 600px) and (max-width: 1139px)  {
    grid-auto-columns: minmax(44px, 1fr);
    grid-gap: 48px;
  }

  @media screen and (min-width: 1140px) {
    grid-auto-columns: minmax(42px, 1fr);
    grid-gap: 48px;
  }
}


.element {
  display: grid;
  background: rgba(0,0,0,.3);
  grid-column: span 3;
  grid-row-start: 2; // REMOVE THIS

  @media screen and (min-width: 600px) and (max-width: 1139px) {
    grid-column: span 3;
  }

  @media screen and (min-width: 1140px) {
    grid-column: span 4;
  }
}
.element img {
  width: 100%;
}

HTML:

<section class="section">
  <div class="container">
    <div class="samba-grid">
 <div class="element">
        <img src="https://placebear.com/400/500" alt="">
        <div class="copy">
          Lorem, ipsum dolor sit amet consectetur adipisicing elit. Sint, eveniet commodi?
        </div>
      </div>
      <div class="element">
        <img src="https://placebear.com/400/500" alt="">
        <div class="copy">
          Lorem, ipsum dolor sit amet consectetur adipisicing elit. Sint, eveniet commodi?
        </div>
      </div>
      <div class="element">
        <img src="https://placebear.com/400/500" alt="">
        <div class="copy">
          Lorem, ipsum dolor sit amet consectetur adipisicing elit. Sint, eveniet commodi?
        </div>
      </div>
      <div class="element">
        <img src="https://placebear.com/400/500" alt="">
        <div class="copy">
          Lorem, ipsum dolor sit amet consectetur adipisicing elit. Sint, eveniet commodi?
        </div>
      </div>
      <div class="element">
        <img src="https://placebear.com/400/500" alt="">
        <div class="copy">
          Lorem, ipsum dolor sit amet consectetur adipisicing elit. Sint, eveniet commodi?
        </div>
      </div>
      <div class="element">
        <img src="https://placebear.com/400/500" alt="">
        <div class="copy">
          Lorem, ipsum dolor sit amet consectetur adipisicing elit. Sint, eveniet commodi?
        </div>
      </div>
      <div class="element">
        <img src="https://placebear.com/400/500" alt="">
        <div class="copy">
          Lorem, ipsum dolor sit amet consectetur adipisicing elit. Sint, eveniet commodi?
        </div>
      </div>
      <div class="element">
        <img src="https://placebear.com/400/500" alt="">
        <div class="copy">
          Lorem, ipsum dolor sit amet consectetur adipisicing elit. Sint, eveniet commodi?
        </div>
      </div>

    </div>


  </div>
</section>

^ note this video shows grid-items stack in rows doesn't scroll horizontal.

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Armeen Moon
  • 18,061
  • 35
  • 120
  • 233

1 Answers1

7

You can define the grid-auto-columns to be a percentage in order to control this. The formula should be (100% - (N-1)*Gap)/N where N is number of element you want to show:

Here is a simplified example with 3 breakpoints:

.grid {
  display:grid;
  grid-auto-flow: column;
  grid-auto-columns:calc((100% - 2*10px)/3); /*3 items visible*/
  grid-gap:10px;
  margin:10px;
  max-width:800px;
  overflow:auto;
}
img {
  max-width:100%;
}

@media all and (max-width:800px) {
.grid {
  grid-auto-columns:calc((100% - 5px)/2); /*two items visible*/
  grid-gap:5px;
 }
}

@media all and (max-width:400px) {
.grid {
  grid-auto-columns:100%; /*one item visible*/
  grid-gap:5px;
 }
}
<div class="grid">
 <img src="https://picsum.photos/500/500?image=0">
 <img src="https://picsum.photos/500/500?image=0">
 <img src="https://picsum.photos/500/500?image=0">
 <img src="https://picsum.photos/500/500?image=0">
 <img src="https://picsum.photos/500/500?image=0">
 <img src="https://picsum.photos/500/500?image=0">
 <img src="https://picsum.photos/500/500?image=0">
 <img src="https://picsum.photos/500/500?image=0">
 <img src="https://picsum.photos/500/500?image=0">
</div>

A code that you can optimize with CSS variables:

.grid {
  --n:3; /*3 visible items */
  --g:10px;
  
  display:grid;
  grid-auto-flow: column;
  grid-auto-columns:calc((100% - (var(--n) - 1)*var(--g))/var(--n)); 
  grid-gap:var(--g);
  margin:10px;
  max-width:800px;
  overflow:auto;
}
img {
  max-width:100%;
}

@media all and (max-width:800px) {
.grid {
  --n:2; /*2 visible items */
  --g:5px;
 }
}

@media all and (max-width:400px) {
.grid {
  --n:1; /*1 visible item */
 }
}
<div class="grid">
 <img src="https://picsum.photos/500/500?image=0">
 <img src="https://picsum.photos/500/500?image=0">
 <img src="https://picsum.photos/500/500?image=0">
 <img src="https://picsum.photos/500/500?image=0">
 <img src="https://picsum.photos/500/500?image=0">
 <img src="https://picsum.photos/500/500?image=0">
 <img src="https://picsum.photos/500/500?image=0">
 <img src="https://picsum.photos/500/500?image=0">
 <img src="https://picsum.photos/500/500?image=0">
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • An amazing solution. Especially needed if you use `scroll-snap` since you want the container to scroll by `N` of items. – certainlyakey Aug 02 '20 at 11:06
  • Hi, nice solution. How would I get round [this problem?](https://stackoverflow.com/questions/66445120/images-with-certain-resolutions-in-grid-change-height-on-resize) Thanks – Tom Mar 02 '21 at 21:28