Is it possible to make a CSS grid wrap without using media queries?
In my case, I have a non-deterministic number of items that I want placed in a grid and I want that grid to wrap. Using Flexbox, I'm unable to reliably space things nicely. I'd like to avoid a bunch of media queries too.
Here's some sample code:
.grid {_x000D_
display: grid;_x000D_
grid-gap: 10px;_x000D_
grid-auto-flow: column;_x000D_
grid-template-columns: 186px 186px 186px 186px;_x000D_
}_x000D_
_x000D_
.grid > * {_x000D_
background-color: green;_x000D_
height: 200px;_x000D_
}
_x000D_
<div class="grid">_x000D_
<div>1</div>_x000D_
<div>2</div>_x000D_
<div>3</div>_x000D_
<div>4</div>_x000D_
</div>
_x000D_
And here's a GIF image:
As a side-note, if anyone can tell me how I could avoid specifying the width of all the items like I am with grid-template-columns
that would be great. I'd prefer the children to specify their own width.
Use either auto-fill
or auto-fit
as the first argument of the repeat()
notation.
<auto-repeat>
variant of the repeat()
notation:
repeat( [ auto-fill | auto-fit ] , [ <line-names>? <fixed-size> ]+ <line-names>? )
auto-fill
When
auto-fill
is given as the repetition number, if the grid container has a definite size or max size in the relevant axis, then the number of repetitions is the largest possible positive integer that does not cause the grid to overflow its grid container.
.grid {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, 186px);
}
.grid>* {
background-color: green;
height: 200px;
}
_x000D_
<div class="grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
_x000D_
The grid will repeat as many tracks as possible without overflowing its container.
In this case, given the example above (see image), only 5 tracks can fit the grid-container without overflowing. There are only 4 items in our grid, so a fifth one is created as an empty track within the remaining space.
The rest of the remaining space, track #6, ends the explicit grid. This means there was not enough space to place another track.
auto-fit
The
auto-fit
keyword behaves the same asauto-fill
, except that after grid item placement any empty repeated tracks are collapsed.
.grid {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fit, 186px);
}
.grid>* {
background-color: green;
height: 200px;
}
_x000D_
<div class="grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
_x000D_
The grid will still repeat as many tracks as possible without overflowing its container, but the empty tracks will be collapsed to 0
.
A collapsed track is treated as having a fixed track sizing function of 0px
.
Unlike the auto-fill
image example, the empty fifth track is collapsed, ending the explicit grid right after the 4th item.
auto-fill
vs auto-fit
The difference between the two is noticeable when the minmax()
function is used.
Use minmax(186px, 1fr)
to range the items from 186px
to a fraction of the leftover space in the grid container.
When using auto-fill
, the items will grow once there is no space to place empty tracks.
.grid {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(186px, 1fr));
}
.grid>* {
background-color: green;
height: 200px;
}
_x000D_
<div class="grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
_x000D_
When using auto-fit
, the items will grow to fill the remaining space because all the empty tracks will be collapsed to 0px
.
.grid {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fit, minmax(186px, 1fr));
}
.grid>* {
background-color: green;
height: 200px;
}
_x000D_
<div class="grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
_x000D_
Playground:
Inspecting auto-fill tracks
Inspecting auto-fit tracks
You want either auto-fit
or auto-fill
inside the repeat()
function:
grid-template-columns: repeat(auto-fit, 186px);
The difference between the two becomes apparent if you also use a minmax()
to allow for flexible column sizes:
grid-template-columns: repeat(auto-fill, minmax(186px, 1fr));
This allows your columns to flex in size, ranging from 186 pixels to equal-width columns stretching across the full width of the container. auto-fill
will create as many columns as will fit in the width. If, say, five columns fit, even though you have only four grid items, there will be a fifth empty column:
Using auto-fit
instead will prevent empty columns, stretching yours further if necessary:
You may be looking for auto-fill
:
grid-template-columns: repeat(auto-fill, 186px);
Demo: http://codepen.io/alanbuchanan/pen/wJRMox
To use up the available space more efficiently, you could use minmax
, and pass in auto
as the second argument:
grid-template-columns: repeat(auto-fill, minmax(186px, auto));
Demo: http://codepen.io/alanbuchanan/pen/jBXWLR
If you don't want the empty columns, you could use auto-fit
instead of auto-fill
.
I had a similar situation. On top of what you did, I wanted to center my columns in the container while not allowing empty columns to for them left or right:
.grid {
display: grid;
grid-gap: 10px;
justify-content: center;
grid-template-columns: repeat(auto-fit, minmax(200px, auto));
}
Here's my attempt. Excuse the fluff, I was feeling extra creative.
My method is a parent div
with fixed dimensions. The rest is just fitting the content inside that div accordingly.
This will rescale the images regardless of the aspect ratio. There will be no hard cropping either.
body {_x000D_
background: #131418;_x000D_
text-align: center;_x000D_
margin: 0 auto;_x000D_
}_x000D_
_x000D_
.my-image-parent {_x000D_
display: inline-block;_x000D_
width: 300px;_x000D_
height: 300px;_x000D_
line-height: 300px; /* Should match your div height */_x000D_
text-align: center;_x000D_
font-size: 0;_x000D_
}_x000D_
_x000D_
/* Start demonstration background fluff */_x000D_
.bg1 {background: url(https://unsplash.it/801/799);}_x000D_
.bg2 {background: url(https://unsplash.it/799/800);}_x000D_
.bg3 {background: url(https://unsplash.it/800/799);}_x000D_
.bg4 {background: url(https://unsplash.it/801/801);}_x000D_
.bg5 {background: url(https://unsplash.it/802/800);}_x000D_
.bg6 {background: url(https://unsplash.it/800/802);}_x000D_
.bg7 {background: url(https://unsplash.it/802/802);}_x000D_
.bg8 {background: url(https://unsplash.it/803/800);}_x000D_
.bg9 {background: url(https://unsplash.it/800/803);}_x000D_
.bg10 {background: url(https://unsplash.it/803/803);}_x000D_
.bg11 {background: url(https://unsplash.it/803/799);}_x000D_
.bg12 {background: url(https://unsplash.it/799/803);}_x000D_
.bg13 {background: url(https://unsplash.it/806/799);}_x000D_
.bg14 {background: url(https://unsplash.it/805/799);}_x000D_
.bg15 {background: url(https://unsplash.it/798/804);}_x000D_
.bg16 {background: url(https://unsplash.it/804/799);}_x000D_
.bg17 {background: url(https://unsplash.it/804/804);}_x000D_
.bg18 {background: url(https://unsplash.it/799/804);}_x000D_
.bg19 {background: url(https://unsplash.it/798/803);}_x000D_
.bg20 {background: url(https://unsplash.it/803/797);}_x000D_
/* end demonstration background fluff */_x000D_
_x000D_
.my-image {_x000D_
width: auto;_x000D_
height: 100%;_x000D_
vertical-align: middle;_x000D_
background-size: contain;_x000D_
background-position: center;_x000D_
background-repeat: no-repeat;_x000D_
}
_x000D_
<div class="my-image-parent">_x000D_
<div class="my-image bg1"></div>_x000D_
</div>_x000D_
_x000D_
<div class="my-image-parent">_x000D_
<div class="my-image bg2"></div>_x000D_
</div>_x000D_
_x000D_
<div class="my-image-parent">_x000D_
<div class="my-image bg3"></div>_x000D_
</div>_x000D_
_x000D_
<div class="my-image-parent">_x000D_
<div class="my-image bg4"></div>_x000D_
</div>_x000D_
_x000D_
<div class="my-image-parent">_x000D_
<div class="my-image bg5"></div>_x000D_
</div>_x000D_
_x000D_
<div class="my-image-parent">_x000D_
<div class="my-image bg6"></div>_x000D_
</div>_x000D_
_x000D_
<div class="my-image-parent">_x000D_
<div class="my-image bg7"></div>_x000D_
</div>_x000D_
_x000D_
<div class="my-image-parent">_x000D_
<div class="my-image bg8"></div>_x000D_
</div>_x000D_
_x000D_
<div class="my-image-parent">_x000D_
<div class="my-image bg9"></div>_x000D_
</div>_x000D_
_x000D_
<div class="my-image-parent">_x000D_
<div class="my-image bg10"></div>_x000D_
</div>_x000D_
_x000D_
<div class="my-image-parent">_x000D_
<div class="my-image bg11"></div>_x000D_
</div>_x000D_
_x000D_
<div class="my-image-parent">_x000D_
<div class="my-image bg12"></div>_x000D_
</div>_x000D_
_x000D_
<div class="my-image-parent">_x000D_
<div class="my-image bg13"></div>_x000D_
</div>_x000D_
_x000D_
<div class="my-image-parent">_x000D_
<div class="my-image bg14"></div>_x000D_
</div>_x000D_
_x000D_
<div class="my-image-parent">_x000D_
<div class="my-image bg15"></div>_x000D_
</div>_x000D_
_x000D_
<div class="my-image-parent">_x000D_
<div class="my-image bg16"></div>_x000D_
</div>_x000D_
_x000D_
<div class="my-image-parent">_x000D_
<div class="my-image bg17"></div>_x000D_
</div>_x000D_
_x000D_
<div class="my-image-parent">_x000D_
<div class="my-image bg18"></div>_x000D_
</div>_x000D_
_x000D_
<div class="my-image-parent">_x000D_
<div class="my-image bg19"></div>_x000D_
</div>_x000D_
_x000D_
<div class="my-image-parent">_x000D_
<div class="my-image bg20"></div>_x000D_
</div>
_x000D_
Source: Stackoverflow.com