4

I have a layout in which multiple items will be aligned in a grid. Let's use the following as an example:

.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 20px;
}

.grid-item {
  display: block;
  width: 100%;
  background-color: purple;
  color: white;
  text-align: center;
  padding: 30px 5px;
}
<div class="grid-container">
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
</div>

In the above code, the grid will repeat 3 columns per row and each item will expand to 1/3 of the row width. The problem is that in a responsive situation, the grid will always repeat 3 columns.

If I change the repeat value to auto-fit and adjust the column sizing to use minmax I can control how the page scales down and reduce the col width and count to some sane value. So adjusted code would look something like this:

.grid-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px,1fr));
  grid-gap: 20px;
}

.grid-item {
  display: block;
  width: 100%;
  background-color: teal;
  color: white;
  text-align: center;
  padding: 30px 5px;
}
<div class="grid-container">
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
</div>

This works well scaling down, but here is where I am having problems - I want to cap the number of cols at 3 when the page scales up. Ideally, I would like to use minmax in the repeat directive like this:

grid-template-columns: repeat( minmax(1, 3), minmax(300px, 1fr) );

but of course this doesn't work. How can I limit repeat to 3 columns while still maintaining my downscale settings with auto-fit?

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Chase
  • 3,009
  • 3
  • 17
  • 23

3 Answers3

3

I don't think you can set a max-limit on the number of columns using auto-fit or auto-fill. By definition, they will create as many tracks as can fit in the container without overflowing:

§ 7.2.2.2. Repeat-to-fill: auto-fill and auto-fit repetitions

When auto-fill [or auto-fit] is given as the repetition number ... then the number of repetitions is the largest possible positive integer that does not cause the grid to overflow its grid container.

And you can't set the max value of the minmax() function to 30%, because then you run into the same problem you had in your first example:

grid-template-columns: repeat(3, 1fr)

Namely, the column tracks become fixed on all screen sizes, and the layout is not responsive.

I understand that you're looking for a solution that doesn't require media queries. But if you want to use grid layout, I think media queries may be your best bet.

Otherwise, consider flex layout:

jsFiddle demo

.grid-container {
  display: flex;
  flex-wrap: wrap;
}

.grid-item {
  width: 30%;
  min-width: 300px;
  flex-grow: 1;
  background-color: teal;
  color: white;
  text-align: center;
  padding: 30px 5px;
  border: 5px solid white;
}

* {
  box-sizing: border-box;
}
<div class="grid-container">
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
  <div class="grid-item">Item</div>
</div>

If you go the flex route, then read this post, too:

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • It has potential but I also noticed a case where when cols are reduced to 2 the last child expands to 2x the items in the grid, or 100% the container. I would want all items equal width. – Chase Nov 09 '18 at 04:08
  • That's why I referred you to the post mentioned at the bottom. – Michael Benjamin Nov 09 '18 at 04:09
  • No clean or easy solutions here using grid or flex. At least as far as I can see at the moment. Good luck. – Michael Benjamin Nov 09 '18 at 04:15
2

if I understand correctly what you can do is set a media query for larger screens. Lets say you want to show a 3 column grid for screens over 992px you can use something like this

@media only screen and (min-width: 992px){
  .grid-container{
    grid-template-columns: repeat(3, 1fr);
  }
}

Let me know if that helps you! check it here https://codepen.io/anon/pen/Krzbmz

MartinBA
  • 797
  • 1
  • 5
  • 15
  • That would in fact work, thanks. What I am trying to determine though is if this solution is acceptable as the "css grid way" of how to handle it instead of a duct tape hack. If no one else chimes in with some unknown-to-me param for grid settings that solves this, then I'll use breakpoints. I'll wait another day or so to see. – Chase Nov 09 '18 at 03:49
0

I solved a similar issue by setting max-width to the grid. I had my columns as repeat(auto-fit, 150px). I wanted a max number of columns as x4 with 50px gap. So max-width of grid set to 800px.

  • 1
    Hi and Welcome to SO. please take the [tour] first. Then read [how to ask questions here](https://stackoverflow.com/help/how-to-ask). SO is not a Forum but a Q&A site. Do not post an answer to ask a simliar question. Open your own question! – tacoshy Aug 13 '21 at 18:13