Reputation: 668
With a flex container and flex-wrap: wrap
set you can align overflowing items to the center using justify-content: center
.
Is there a way to achieve the same behaviour for overflowing grid items using CSS grid?
I've created a pen showing the desired flex behavior
.container-flex {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.container-flex .item {
width: 33.33%;
background: green;
border: 1px solid;
}
.container-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.container-grid .item {
background: red;
border: 1px solid;
}
* {
box-sizing: border-box;
}
<h3>Flex</h3>
<div class="container-flex">
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
</div>
<h3>Grid</h3>
<div class="container-grid">
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
</div>
https://codepen.io/JoeHastings/pen/PeEjjR
Upvotes: 12
Views: 14744
Reputation: 371231
Flex and Grid are different animals, so a behavior that's simple in flex may not translate well to grid.
A flex item can center across the container because flex layout works with flex lines. A flex line is a non-intersecting row or column.
When a flex item is asked to center in the flex line, it has access to the available space on the entire line. This makes centering simple and easy.
In grid layout, however, there are tracks, which are intersecting rows and columns. For example, in your layout there are three columns. These columns cut across the row, dividing it into three separate sections, and grid items are confined to a section.
Therefore, a grid item cannot automatically be centered on a row using keyword alignment properties (such as justify-content
or justify-self
) because the intersecting tracks restrict movement.
It is possible to make a grid area span the entire row/column, which then clears the way across the entire track, allowing a grid item to be centered horizontally (justify-content: center
) or vertically (align-self: center
), but this behavior must be explicitly defined.
For the grid item to be centered across the row in a dynamic layout the container would need to have only one column, or the item would need to be explicitly moved to the center using something like line-based placement. Otherwise, use flexbox.
Upvotes: 10
Reputation: 113
Late to this party. But at least in 3 grid row scenarios like this you can use a mixture of :nth-of-type
and :last-of-type
to target the trailing item and place it in the column. Kind of piggy backing off of the answer above you get:
.container-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.item {
background: red;
border: 1px solid;
}
/* target the last item, if its the only one in the row */
.item:last-of-type:nth-of-type(3n+1) {
background:purple;
grid-column:2;
}
This, unfortunately, doesn't scale out super well to any other row count due to the problems listed in the above answers, but maybe will help someone.
Upvotes: 0
Reputation: 19735
Not the way you want with flex. You have to be precise with CSS-Grid,
<h3>Grid</h3>
<div class="container-grid">
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item">item</div>
<div class="item-mid">item</div>
</div>
.container-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.item {
background: red;
border: 1px solid;
}
.item-mid{
background:purple;
grid-column:2/1;
}
Also, look here,
(this is not wrapping, however)
Upvotes: 1