How to make CSS Grid items take up remaining space?

A grid is a series of intersecting rows and columns.

You want the two items in the second column to automatically adjust their row height based on their content height.

That's not how a grid works. Such changes to the row height in the second column would also affect the first column.

If you must use CSS Grid, then what I would do is give the container, let's say, 12 rows, then have items span rows as necessary.

.grid {
  display: grid;
  grid-template-columns: 1fr 3fr;
  grid-template-rows: repeat(12, 15px);
}

.one {
  grid-row: 1 / -1;
  background: red;
}

.two {
  grid-row: span 10;
  background: lightgreen;
}

.three {
  grid-row: span 2;
  background: aqua;
}

.grid > div {
  display: flex;
  align-items: center;
  justify-content: center;
}
<div class="grid">
  <div class="one">One</div>
  <div class="two">Two</div>
  <div class="three">Three</div>
</div>

Otherwise, you can try a flexbox solution.

.grid {
  display: flex;
  flex-flow: column wrap;
  height: 200px;
}

.one {
  flex: 0 0 100%;
  width: 30%;
  background: red;
}

.two {
  flex: 1 0 1px;
  width: 70%;
  background: lightgreen;
}

.three {
  background: aqua;
}

.grid>div {
  display: flex;
  align-items: center;
  justify-content: center;
}
<div class="grid">
  <div class="one">One</div>
  <div class="two">Two</div>
  <div class="three">Three</div>
</div>

When using grid, and you have grid template area used, and by chance you gave a particular area a width, you are left with a space grid does automatically. In this situation, let grid-template-columns be either min-content or max-content, so that it adjusts its position automatically.


Adding grid-template-rows: 1fr min-content; to your .grid will get you exactly what you're after :).

.grid {
  display: grid;
  grid-template-columns: 1fr 3fr;
  grid-template-rows: 1fr min-content;
  grid-template-areas:
    "one two"
    "one three"
}

.one {
  background: red;
  grid-area: one;
  padding: 50px 0;
}

.two {
  background: green;
  grid-area: two;
}

.three {
  background: blue;
  grid-area: three;
}
<div class="grid">
  <div class="one">
    One
  </div>
  <div class="two">
    Two
  </div>
  <div class="three">
    Three
  </div>
</div>

Jens edits: For better browser support this can be used instead: grid-template-rows: 1fr auto;, at least in this exact case.