9

My target is to use CSS grid layout for a two-column masonry layout of boxes. Given an element with children:

<section>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</section>

bring the children to sort themselves alternately into columns. My idea was to have two grid areas left and right and telling the children to split into them:

section {
  display: grid;
  grid-template-areas: "left right";
}

div:nth-child(odd) {
  grid-area: left;
}

div:nth-child(even) {
  grid-area: right;
}

Here's a JSBin that illustrates my current state: https://jsbin.com/zaduruv/edit?html,css,output

Unfortunately, the elements react quite identical to as if they had position:absolute set. That is, they all crowd towards the top and overlap one another.

Is there any possibility with the CSS grid layout properties to bring the children to line up in the columns, like they'd do normally with position: static?

Boldewyn
  • 75,918
  • 43
  • 139
  • 205
  • have you looked at https://css-tricks.com/snippets/css/complete-guide-grid/? – Winter Mar 09 '17 at 08:17
  • I tried to solve this using flexbox: `https://jsbin.com/tujuzumaca/edit?html,css,output` the only thing you need to make sure is not to give fixed height to the DIVs but to let it take height on its own according to the content. – ANshul Sharma Mar 09 '17 at 08:35
  • @Winter I actually linked to that page in an answer an hour ago ;-) http://stackoverflow.com/questions/21588420/how-to-bring-two-div-in-same-line/42689423#42689423 – Boldewyn Mar 09 '17 at 08:38
  • @ANshulSharma I think we misunderstood one another. The aim is for the boxes, that do have different heights based on their content, to be laid flush out one under the other, without gaps. I solved this with flexbox, too, using `flex-direction: column`, but it has the disadvantage, that I need to set a fixed height on the `section`, otherwise the children wouldn't wrap into a second column. Hence my idea to try and use grid layout. – Boldewyn Mar 09 '17 at 08:44
  • possible guidance: http://stackoverflow.com/q/34480760/3597276 – Michael Benjamin Mar 20 '17 at 20:17

2 Answers2

2

You can't. Since elements can overlap each other in a CSS grid, it doesn't even try to align them. As its name suggests, it is a grid, not a column layout.

A better solution would be to use CSS multi-column layout, as the snippet below.

The only problem with the multi-column layout is, that it distributes the divs vertically instead of horizontally, so you get this:

1 4
2 5
3 6

instead of this:

1 2 
3 4
5 6

section {
    -webkit-column-count: 2; /* Chrome, Safari, Opera */
    -moz-column-count: 2; /* Firefox */
    column-count: 2;
    -webkit-column-gap: 0;
    -moz-column-gap: 0;
    column-gap: 0;
    width: 500px;
    background-color: #e0e0e0;
}

div {
  width: 250px;
  display: inline-block;
}

div:nth-child(1) {
  background-color: #c1c0c1;
  height: 100px;
}

div:nth-child(2) {
  background-color: #fedbc1;
  height: 50px;
}

div:nth-child(3) {
  background-color: #dec34a;
  height: 130px;
}

div:nth-child(4) {
  background-color: #ce3294;
  height: 110px;
}

div:nth-child(5) {
  background-color: #99deac;
  height: 80px;
}

div:nth-child(6) {
  background-color: #aade34;
  height: 190px;
}
<section>
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
</section>
beerwin
  • 7,423
  • 5
  • 39
  • 50
  • Thanks for the answer! Yes, I suspected that that's not grid's scope to do something like that. I experimented with CSS columns, too, but ran into issues, where browsers ignored a child's `break-inside: avoid`, and smeared that child's content over two columns. – Boldewyn Mar 09 '17 at 11:38
  • I'm inclined right now to just give up, add two wrapper elements and sort the children in there manually. Or getting good ol' Masonry.js back in place. – Boldewyn Mar 09 '17 at 11:39
0

You have to ditch the grid-areas for this one and work with grid-column-start. Otherwise everything will be put into the same area. https://jsbin.com/peqiwodoba/edit?html,css,output

div:nth-child(odd) {
}

div:nth-child(even) {
  grid-column-start: 2;
}
Björn Tantau
  • 1,456
  • 13
  • 10