Can I fill a grid container from the center?

Viewed 191

Is there a way to fill a grid from the center?

I have a CSS grid container which has a dynamic content(it gets updated so the number of children is not fixed) that looks like this:

#container { 
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

and if I had all 4 columns filled it would look like this :

1 2 3 4 //Numbers that represent containers children

Which is okay for me, but the problem comes when I have, for instance, only two divs inside my main container and then it looks like this:

1 2 0 0

And what I would like to achieve is this:

0 1 2 0
2 Answers

NEW ANSWER:

If you want to stick to just grid and assuming you only have four columns and the possible configurations are 0 1 0 0, 0 1 1 0, 0 1 1 1, 1 1 1 1 then following CSS works:

.container {
  display: grid;
  grid-template-columns: 25% 25% 25% 25%;
}

.col {
  height: 50px;
  background: green;
}

.col:first-child {
  grid-column-start: 2;
}

.col:first-child:nth-last-child(4) {
  grid-column-start: 1;
}

Assuming the HTML you have:

<div class="container">
  <div class="col">
  Col
  </div>
  <!-- Other Cols Here -->
</div>

Working Fiddle

ORIGINAL ANSWER:

For grids, it's not possible to center a dynamic number of elements. Grid layout is suitable for layouts with a fixed number of elements.

Refer to the use of grid vs flex layouts. Your problem is more suitable to be solved by flex where you use justify-content: center on flex containers to achieve centered children.

To achieve centered children, modify your styles on #container div:

#container { 
  display: flex;
  justify-content: center;
}

Scenario where you want 0 1 0 0, 0 1 1 0, 0 1 1 1, 1 1 1 1 and assuming there are only four columns:

.container {
  display: flex;
  justify-content: center;
}

.col {
  width: 25%;
  height: 50px;
  background: green;
}

.col:last-child:not(:nth-child(even)):first-child {
  margin-left: -25%;
}

.col:last-child:not(:nth-child(even)):not(:first-child) {
  margin-right: -25%;
}

I assume your markup will be something like this:

<div class="container">
  <div class="col">
  Col
  </div>
  <!-- Other Columns Go Here -->
</div>

Working Fiddle

As everyone already stated Flexbox is much suited for this, However (if i'm not missing anything)

A combination of the following properties should do the trick

grid-auto-flow: column;
grid-auto-columns: 25%; // assumes 4 columns
justify-content: center;

document.querySelectorAll('input')[0].onclick = () => { document.querySelector('[container]').append(document.createElement('div'))}
document.querySelectorAll('input')[1].onclick = () => {document.querySelector('[container]').innerHTML = '<div></div>';}
body * {
  padding: 10px;
  border: 1px solid;
}

[container] {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 25%;
  justify-content: center;
}

[container]>div {
  height: 50px;
  background: orange;
}
<input type="button" value="Add Column" />
<input type="button" value="reset" />
<div container>
  <div></div>
</div>

Related