Centering in CSS grid with a fixed width column
Asked Answered
S

3

6

Im trying to make a simple CSS centered grid layout. I know that when I use justify-items: center, the items inside a grid container are supposed to align horizontally, but when I specify a column width in pixels like this grid-template-columns: repeat(3, 100px) the whole grid return to normal. So is there any way to make the grid items centered but in same time specify the column width in pixels? Here are my example:

    <div class="container">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
    </div>
.container {
    background-color: #aa96da;
    display: grid;
    justify-items: center;
    grid-gap: 20px;
    grid-template-rows: repeat(3, 1fr);

    /*Only if I change this 100px to '1fr' the justify-items will work */
    grid-template-columns: repeat(3, 100px);
}

.item {
    width: 100px;
    height: 100px;
    background-color: green;
}
Stefan answered 29/4, 2020 at 1:14 Comment(2)
how you want to center an item with width=100px inside a column with the same width? there is no room for centringHobbyhorse
What I want is to center the whole grid container inside the body not the item inside the particular gridStefan
G
5

Change the justify-items to justify-content and it should work.

.container {
    background-color: #aa96da;
    display: grid;
    /* justify-items: center; */
    justify-content: center;
    grid-gap: 20px;
    grid-template-rows: repeat(3, 1fr);

    /*Only if I change this 100px to '1fr' the justify-items will work */
    grid-template-columns: repeat(3,  100px);
}

.item {
    width: 100px;
    height: 100px;
    background-color: green;
}
 <div class="container">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
</div>
Grallatorial answered 29/4, 2020 at 1:32 Comment(0)
S
3

Short answer: You want justify-content not justify-items

.container {
  background-color: #aa96da;
  display: grid;
  justify-content: center; /* -items to -content */
  grid-gap: 20px;
  grid-template-rows: repeat(3, 1fr);
  /*Only if I change this 100px to '1fr' the justify-items will work */
  grid-template-columns: repeat(3, 100px);
}

.item {
  width: 100px;
  height: 100px;
  background-color: green;
}
<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

Long answer:

There's a difference between the grid item and the space it lives in.

When you define a grid, you're only defining rows/columns of the grid called tracks, Not actually defining where each element goes etc.

The DOM elements only follow the flow of the grid and are placed accordingly, which we can alter using properties like grid-column grid-row

You can look at it like this: enter image description here

As you can see there's The Grid container, The Grid, The Columns, The Rows and then The Grid items.

The Grid items lives in the intersection between the two called The Grid Area (this what makes css grid better than flexbox in some ways)

And justify-items aligns the grid items within that area.


So grid-template-columns: repeat(3, 1fr); This means 3 columns their width is the width of the grid split evenly between them.

Demo

Don't look at the code just the preview

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

[grid] {
  height: 300px;
  display: flex;
  border: 2px solid;
  padding: 10px;
  flex-wrap: wrap;
}

[column] {
  flex: 1 0 calc(100% / 3);
  border: 2px solid;
  display: flex;
  flex-direction:column;
  align-items:center;
  
}

[column]>div {
  width: 100px;
  flex:1;
  background-color: green;
}
<div grid>
  <div column>
    <div>Grid Item</div>
  </div>
  <div column>
    <div>Grid Item</div>
  </div>
  <div column>
    <div>Grid Item</div>
  </div>
  <div column>
    <div>Grid Item</div>
  </div>
  <div column>
    <div>Grid Item</div>
  </div>
  <div column>
    <div>Grid Item</div>
  </div>
  <div column>
    <div>Grid Item</div>
  </div>
  <div column>
    <div>Grid Item</div>
  </div>
  <div column>
    <div>Grid Item</div>
  </div>
</div>

As you can see the grid columns are wider than the grid items 100px which means there space to center stuff, So justify-items: center; will center them inside.

That's why it looks like the grid is centered, But it's actually not reasons why changing to grid-template-columns: repeat(3, 100px); breaks it.


In the case of grid-template-columns: repeat(3, 100px);

Demo

Don't look at the code just the preview

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

[ctr] {
  border: 2px solid;
  padding: 10px;
}

[grid] {
  height: 300px;
  width: 340px;
  display: flex;
  padding: 10px;
  flex-wrap: wrap;
}

[column] {
  flex: 0 0 100px;
  border: 2px solid;
  display: flex;
  flex-direction: column;
  align-items: center;
}

[column]>div {
  width: 100px;
  flex: 1;
  background-color: green;
}
<div ctr>
  <div grid>
    <div column>
      <div>Grid Item</div>
    </div>
    <div column>
      <div>Grid Item</div>
    </div>
    <div column>
      <div>Grid Item</div>
    </div>
    <div column>
      <div>Grid Item</div>
    </div>
    <div column>
      <div>Grid Item</div>
    </div>
    <div column>
      <div>Grid Item</div>
    </div>
    <div column>
      <div>Grid Item</div>
    </div>
    <div column>
      <div>Grid Item</div>
    </div>
    <div column>
      <div>Grid Item</div>
    </div>
  </div>
</div>

As you can see the columns width equal the grid item's so they all fit snugly within the columns and the grid is still empty.

Stewardess answered 29/4, 2020 at 14:7 Comment(2)
Oh, thanks that totally fixed it ! Also after rereading your answer two times, I finally get how the grid layout works and what justify-items and justify-content means.Stefan
@Stefan If you want a more in-depth explanation Box alignment in grid layoutStewardess
D
0

You can try adding the flex property on top of those grid elements and then center it with justify-content:center;

  • index.html:
<div class="centering_items">
       <div class="container">
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
        <div class="item"></div>
      </div>
</div>
  • style.css
.centering_items {
    display: flex;
    justify-content: center;
}

.container {
    background-color: #aa96da;
    display: grid;
    grid-gap: 20px;
    grid-template-rows: repeat(3, 1fr);

    /*Only if I change this 100px to '1fr' the justify-items will work */
    grid-template-columns: repeat(3,  100px);
}

.item {
    width: 100px;
    height: 100px;
    background-color: green;
}
Doerrer answered 10/11, 2022 at 17:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.