How to Get Grid Items of Different Lengths to Wrap

How to get grid items of different lengths to wrap?

Grid items do not actually wrap. The reason you see grid items "wrapping" to the next row is really because the explicit grid is being altered to keep within the constraints stipulated by minmax(). The number of columns generated by repeat() is proportional to the used width of the grid container, and the grid items are laid out one by one according to the number of columns, with new rows being created as necessary.

So, it is not possible to force the second grid item to wrap when there are two columns and there is room in the explicit grid to insert that grid item in the second column. Besides, even if you could tell the second grid item to "wrap", it would mean placing it in a new row in the first column, so its layout will be governed by the first column and not the second. Having it still be sized according to the second column would, of course, break the grid layout entirely.

If the intention is to accommodate smaller screens by wrapping elements to new lines, flex layout should be used, not grid layout. Grid layout is not suitable for this purpose.

Can grid items wrap?

Your layout adds columns and rows:

#grid-container {
display: grid;
grid-template-rows: repeat(var(--grid-rows), 1fr);
grid-template-columns: repeat(var(--grid-cols), 1fr);
}

Columns and rows don't wrap. They append to the existing set of columns or rows.

Hence, grid items in this layout won't wrap. They occupy the cells created by the new tracks.

If you want a layout where the items wrap, use the grid auto-fit or auto-fill functions, which limit the creation of columns or rows to the size of the container. Working together, these functions and limits enable grid items to flow across tracks.

Another option is flexbox, which doesn't generate column or row tracks, just flex lines.

These posts may provide further guidance:

  • How to get grid items of different lengths to wrap?
  • Areas covered by Flexbox which are difficult or impossible to achieve with Grid

CSS grid wrapping

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.

https://www.w3.org/TR/css-grid-1/#valdef-repeat-auto-fill

.grid {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, 186px);
}

.grid>* {
background-color: green;
height: 200px;
}
<div class="grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>

How to specify different size for each grid element and maintain wrapping?

You can try flexbox for this:

.container {

display: flex;

flex-wrap: wrap;

margin:-8px; /*Pay attention to this! You may need overflow:hidden on a parent container*/

}

.child {

background: #aaa;

height: 32px;

min-width: 250px;

flex-basis: 0%;

margin: 8px;

}

.container> :first-child {

flex-grow: 2;

}

.container> :last-child {

flex-grow: 1;

}

.container-grid {

display: grid;

grid-template-columns: minmax(250px, 2fr) minmax(250px, 1fr);

grid-gap:16px;

}

.container-grid > .child {

margin:0;

}
flexbox with wrapping

<div class="container">

<div class="child">Child 1</div>

<div class="child">Child 2</div>

</div>

grid without wrapping:

<div class="container-grid">

<div class="child">Child 1</div>

<div class="child">Child 2</div>

</div>

Align Material UI Grid Items of different length

I've added xs={9} for text-field and xs={3} for the label with style={{ textAlign: 'right' }}(not familiar with material-ui so don't know if there's a better way to apply this).

This is the result: https://codesandbox.io/s/hungry-euclid-n7y8f

CSS Grid won't wrap children when setting grid-row

You can make the text to take the full row and then inside you decrease its width so it only take the needed width. Like that you will block the 1st row and no element can go there.

Here is a simplified example:

.samba-grid {

display: grid;

background: inherit;

width: 100%;

grid-template-columns: repeat(12, 1fr);

grid-gap: 24px;

border:1px solid;

}

.element-header {

grid-row: 1;

grid-column: 1/-1;

}

.element-header > h1 {

/*we take 8 colmuns (without gaps) + 7 gaps*/

width:calc(8*(100% - 11*24px)/12 + 7*24px);

background:red;

margin:0;

}

.samba-grid > span {

height:50px;

grid-column: span 2;

background:green;

}
<div class="samba-grid">

<div class="element-header">

<h1>I am a lot of header text that only goes 8 columsn wide</h1>

</div>

<span></span>

<span></span>

<span></span>

<span></span>

<span></span>

<span></span>

<span></span>

<span></span>

</div>

How can I force this CSS grid to wrap to a new line without specifying minmax sizes?

I don't see how this is possible with the current iteration of CSS Grid.

As you've already discovered, you would at least need to define a fixed minimum width on the columns, in order to force a wrap at some point.

Unfortunately, with automatic repetitions, the minimum length cannot be auto, min-content or max-content alone, because that is forbidden in the specification.

Here's as close as you can get with Grid, as far as I can tell:

.btn-tabs {

display: grid;

grid-template-columns: repeat(auto-fill, minmax(75px, max-content));

width: 20rem;

}

/* original demo styles */

.btn {

font-family: "Arial", sans-serif;

border-bottom: 4px solid #77aaee;

color: #77aaee;

padding: .6rem;

text-decoration: none;

}
<div class="btn-tabs">

<a class="btn" href="#">Button 1</a>

<a class="btn" href="#">Button 2</a>

<a class="btn" href="#">Button 3</a>

<a class="btn" href="#">Button 4</a>

<a class="btn" href="#">Button 5</a>

<a class="btn" href="#">Button 6</a>

</div>


Related Topics



Leave a reply



Submit