38

How can you specify the maximum number of columns when using display: grid;, with it automatically breaking when the content becomes too wide for the space (or smaller than a minimum size)? Is there a way to do this without media queries?

For example, I have the following which won't break into a single column mode when there is not enough room for the content.

#grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-gap: 1em;
}

#grid > div {
  background-color: #ccddaa;
}
<div id="grid">
  <div>text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text</div>
  <div>text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text</div>
  <div>text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text</div>
  <div>text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text</div>
  <div>text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text</div>
  <div>text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text</div>
  <div>text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text</div>
  <div>text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text</div>
  <div>text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text</div>
</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Panda TG Attwood
  • 1,468
  • 2
  • 16
  • 31
  • The canonical is [CSS grid - maximum number of columns without media queries](https://stackoverflow.com/questions/55281598/css-grid-maximum-number-of-columns-without-media-queries) but since you said 'without media queries', I won't dupe-hammer. – TylerH Feb 27 '23 at 19:45

1 Answers1

86

Neither HTML or CSS have any concept of when descendants of a container wrap.

Essentially, the browser renders the document during an initial cascade. It does not reflow the document when a child wraps.

Therefore, to change the number of columns, you will need to set a width limit somewhere along the line or use media queries.

Here's a more in-depth explanation: Make container shrink-to-fit child elements as they wrap


If you can define a column width, then grid layout's auto-fill function makes wrapping easy.

In this example, the number of columns is based entirely on the width of the screen:

#grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); /* see notes below */
  grid-gap: 1em;
}

#grid > div {
  background-color: #ccddaa;
}
<div id="grid">
  <div>text</div>
  <div>text</div>
  <div>text</div>
  <div>text</div>
  <div>text</div>
  <div>text</div>
  <div>text</div>
  <div>text</div>
  <div>text</div>
</div>

jsFiddle demo

Notes:

The auto-fill function allows the grid to line up as many grid tracks (columns or rows) as possible without overflowing the container. This can create similar behavior to flex layout's flex-wrap: wrap.

The minmax() function allows you to set a minimum and maximum size range for a grid track. In the code above, the width of column tracks will be a minimum of 100px and maximum of whatever free space is available.

The fr unit represents a fraction of the available space. It is similar to flex-grow in flex layout.

Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • 2
    Here's another variation: `minmax(100px, 200px)`. It's painfully obvious now, but you don't _have_ to use `fr` units for the 2nd parameter. Before, I was killing myself trying to work with `fr` thinking it was what the 2nd parameter required because that's what a lot of tutorials and sample code use. For my particular situation `px, px` worked like a charm. – Kalnode Sep 15 '18 at 14:30
  • 3
    Can this be used without `repeat`? My first element is `1fr` and my 2nd is `2fr`. – ttugates Aug 10 '20 at 15:12
  • @ttugates There is a solution with `flex` and `flex-wrap`. You can replace the `fr` measurements with appropriate `flex-grow` values or `width`: https://stackoverflow.com/a/49418712/8599834 – theberzi Jan 15 '21 at 09:06
  • 2
    The problem with the flex-wrap solution is that you will not have access to the grid gap property (yet). – return_false Mar 09 '21 at 14:12