Aligning grid items across the entire row/column (like flex items can)
Asked Answered
M

3

12

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

Moleskins answered 8/5, 2018 at 12:51 Comment(7)
in a generic way I would say no as this not what grid is done for ... but for particular case we can always find workaroundsHazlip
Possible duplicate of Centering in CSS GridAmylose
@Amylose I don't think it's a duplicate, that question is about centring text/items inside grid cells which is pretty different to handling wrapping and centring of grid items themselvesMoleskins
I retracted it.Amylose
What make you think Flexbox and Grid can do the same? If, then why do we need both, one would be fine. They are two completely different things, though share some features, and some not. And we need both, as there is no single solution that can handle everything.Tavia
@LGSon I know they are different, but as they are both display based properties they can achieve very similar results in many cases. I wondered if I may have been missing a property or something obvious as it felt more like a grid layout thing, as my desired behaviour was across two axis, and not just a single row or column. Setting percentage widths at different break points and having flex wrap does not feel to me exactly what flex was designed to doMoleskins
@JoeHastings The issue where one need to "use percentage widths at different break points", is more related to the box model itself than a Flexbox issue. For some of those things features were added to CSS Grid, and might also be an upgrade to an upcoming Flexbox v.2.Tavia
T
10

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.

Tumbrel answered 8/5, 2018 at 17:20 Comment(1)
So we are still doomed when we want to center the items but have each row be the same height which is the tallest item's height within the grid - since flex can do the centering well but it does do the row height, grid can do row height but cannot do centeringInjured
A
1

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,

Centering in CSS Grid

(this is not wrapping, however)

Amylose answered 8/5, 2018 at 14:7 Comment(2)
It surprises me grid can't handle this, it makes it a bit annoying when you don't know how many items there are going to be but you want any overflowing items to be centred (without getting javascript involved adding classes) seems like flex and percentage widths is the best option for this caseMoleskins
You can use flex in the grid or create a nested grid. I think the intention is to use flex for that because of the single axis and justify-content.Amylose
H
0

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.

Hydrozoan answered 10/10, 2022 at 18:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.