3

I have a CSS Grid with two areas (left & right). I want to put multiple spans inside these areas, but when I do the following, the items appear on top of each other, as if they were taken out of document flow.

How do I put them back into document flow, so they appear next to each other?

div {
    display: grid;
    grid-template: 1fr 1fr / 1fr;
    grid-template-areas: "left right"
}

div .left {
    grid-area: left;
}

div .right {
    grid-area: right;
}
<div>
    <span class="left">First</span>
    <span class="left">Second</span>
    <span class="left">Third</span>
    <span class="right">Fourth</span>
    <span class="right">Fifth</span>

</div>

Codepen

Post Self
  • 1,471
  • 2
  • 14
  • 34

2 Answers2

2

Full On Grid

Grids are all about columns and rows, so the version without area names (which are only an alias for a location) is:

div {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 50px 50px 50px;
}

div .left {
    grid-column: 1/1;
}

.la {
    grid-row: 1/1;
}

.lb {
    grid-row: 2/2;
}

.lc {
    grid-row: 3/3;
}

div .right {
    grid-column: 2/2;
}
<div>
    <span class="left la">First</span>
    <span class="left lb">Second</span>
    <span class="left lc">Third</span>

    <span class="right la">Fourth</span>
    <span class="right lb">Fifth</span>
</div>

Two Columns, Spans Wherever!

If you just want "two columns" and don't care about positioning the span elements, this might be better for you.

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto;
}

.left {
    grid-column: 1/1;
    grid-row: 1/1;
}

.right {
    grid-column: 2/2;
    grid-row: 1/1;
}

span {
    display: block;
}
<div class="grid">
    <div class="left">
    <span>First</span>
    <span>Second</span>
    <span>Third</span>
    </div>

    <div class="right">
    <span>Fourth</span>
    <span>Fifth</span>
    </div>
</div>
Fenton
  • 241,084
  • 71
  • 387
  • 401
  • The thing is, I want to easily be able to add new spans, this way I'll have to mess with the CSS again – Post Self Nov 01 '17 at 19:26
  • @kim366 I have added an example that might be what you are after... depending on exactly what you need. This won't lay the spans out in a grid, but will give you a grid of two columns that you can add spans to without having to place them. – Fenton Nov 01 '17 at 19:32
  • 1
    Yeah, the second part of this answer is what I had earlier. The problem with that is, that I want to later move the individual items in the grid for a responsive design – Post Self Nov 01 '17 at 19:34
1

Each grid item must get a unique grid-area name.

If you apply the same name to multiple elements then, per the cascade, the last item will be displayed, overlaying the others with the same name.

Here's an example of a proper set-up just for illustration purposes:

div {
  display: grid;
  grid-template-areas: "left1 right1"
                       "left2 right2"
                       "left3 right3"
                       "left4 right4"
                       "left5 right5";
}

span:nth-child(1) { grid-area: left1; }
span:nth-child(2) { grid-area: left2; }
span:nth-child(3) { grid-area: left3; }
span:nth-child(4) { grid-area: right1; }
span:nth-child(5) { grid-area: right2; }
<div>
  <span>First</span>
  <span>Second</span>
  <span>Third</span>
  <span>Fourth</span>
  <span>Fifth</span>
</div>

It appears that you're looking for a vertically flowing grid that wraps after the third row. In that case, here's all you need:

div {
  display: grid;
  grid-template: repeat(3, auto) / 1fr 1fr;
  grid-auto-flow: column;
}
<div>
  <span>First</span>
  <span>Second</span>
  <span>Third</span>
  <span>Fourth</span>
  <span>Fifth</span>
</div>

Learn more about grid-auto-flow: column here: Make grid container fill columns not rows

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • 1
    This is indeed what I need! – Post Self Nov 01 '17 at 19:32
  • One more question: When I do `grid-template-columns: repeat(3, auto) 1fr repeat(2, auto);`, (the `1fr` for the empty area between left and right), the `1fr` gets filled by the first element that should be on the right. Can I force it to be empty without defining areas? – Post Self Nov 01 '17 at 19:48
  • https://codepen.io/anon/pen/WXQXQJ I want `FirstSecondThird` on the left and `FourthFifth` on the right – Post Self Nov 01 '17 at 19:50
  • The problem is you have created six columns for five grid items. So, naturally, the items are populating the columns sequentially. You've given the items no reason to skip the fourth column (which has the `1fr`). – Michael Benjamin Nov 01 '17 at 20:00
  • Hm, this automatically gives the span `display: block` and I can't override it with `display: inline`, which is suboptimal – Post Self Nov 01 '17 at 20:28
  • Once you create a grid container all children become grid items and their display property is taken over by the Grid. Yes, they are considered *blockified* but in the context of a grid container. What are you trying to do? There should be no need to set grid items to `display: inline` when you have so many grid properties and methods. – Michael Benjamin Nov 01 '17 at 20:40
  • Instead of a `span`, in my example I am using an `a`, and with the `margin-left: auto` I have a link that's 500px wide. So it's like I did `padding-left`. – Post Self Nov 01 '17 at 20:49
  • When your element is a grid item, it's type doesn't make a difference in terms of its `display` value. It could be a `span`, `a`, `div`, `section`, etc. It will always be blockified per grid formatting rules. – Michael Benjamin Nov 02 '17 at 00:35
  • Ok, sure. I just put it inside a `span`, now it's working – Post Self Nov 02 '17 at 09:41