CSS grid minmax() with max-width of 100%
Asked Answered
L

2

6

This code uses CSS grid with minmax(30rem, 1fr).

grid-template-columns: repeat(auto-fill, minmax(30rem, 1fr));

Everything works fine, but when the viewport parent container gets smaller than 30rem, a horizontal scrollbar appears. I would need something like minmax(min(30rem, 100%), 1fr)). Any idea how to achieve that?

https://codepen.io/anon/pen/LmEyer

ul {
  list-style-type: none;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(30rem, 1fr));
  grid-auto-rows: 1fr;
  grid-gap: 10px;
}

li {
  background-color: #aaa;
  padding: 0.5rem;
}
<ul class="list">
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
<ul>
Loganloganberry answered 19/4, 2018 at 11:7 Comment(0)
P
2

You answered the question yourself!! you can use the min() function to achieve this:

codepen

.grid {
  display: grid;
  grid-template-columns:
    repeat(
      auto-fit,
      minmax(min(100%, 30rem), 1fr)
    );
  gap: 20px;
}

I recommend this article to learn more about combine clamp and min() with grid-template-column

Portly answered 2/4, 2023 at 9:38 Comment(1)
You are right. I guess the function nesting was not available 5 years ago. Or I did a when trying it out.Loganloganberry
G
1

Sounds like you have a breakpoint when the screen width is 30rem. That calls for a media query.

Add this to your code:

@media (max-width: 30rem) {
   ul { grid-template-columns: 1fr; }
}

revised codepen

ul {
  list-style-type: none;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(30rem, 1fr));
  grid-auto-rows: 1fr;
  grid-gap: 10px;
}

li {
  background-color: #aaa;
  padding: 0.5rem;
}

@media (max-width: 30rem) {
  ul {
    grid-template-columns: 1fr;
  }
}
<ul class="list">
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
  <li>grid item</li>
<ul>
Gwenngwenneth answered 19/4, 2018 at 17:18 Comment(4)
1. The media query should take the grid-gap into account. So it should read @media (max-width: calc(30rem + 2 * 10px)), but that is not widely supported, currently.Loganloganberry
2. Unfortunately, this only works if the grid is on root level. It does not work if this grid is in a container narrower than the viewport. (Yes, my original question was about viewport. But that was for simplicity.)Loganloganberry
No need to factor in a grid-column-gap (which only render between items). Once the screen reaches 30rem, there is only one column, and no gap. @LoganloganberryGwenngwenneth
1. @Michael_B Yes and no. It's not the grid-gap, you are right about that. But 30rem is not the correct value to avoid scrollbars (tested your codepen in several browsers). In this case, it's the body's margin that you have to factor in.Loganloganberry

© 2022 - 2024 — McMap. All rights reserved.