quieri
quieri

Reputation: 344

Let CSS grid row fill available space

I'm working with CSS-grids and I want the last row of my CSS-grid to use all remaining space in the wrapper but at the same time I want all other rows to follow the min-content-strategy.

CSS for the wrapper:

.grid {
  width: 100%;
  height: 100%;
  display: grid;
  grid-template-columns: 100px auto;
  grid-auto-rows: min-content;
  row-gap: 7px;
  justify-items: start;
  align-items: start;
}

My initial idea how to achieve this was to simply add margin-top: auto to the button as one would do with flexbox. I have also tried to set grid-auto-rows: auto for the grid wrapper but it does not work either.

Left: How it looks right now | Right: Desired result

Edit: Example code: https://jsfiddle.net/xt139o2g/ (I want button to appear in lower right corner of the wrapper div)

.wrapper {
  border: 1px solid blue;
  height: 300px;
  width: 250px;
  padding: 10px;
}

.grid {
  width: 100%;
  height: 100%;
  display: grid;
  grid-template-columns: 100px auto;
  grid-auto-rows: min-content;
  row-gap: 7px;
  justify-items: start;
  align-items: start;
}

.button {
  grid-column: 1 / -1;
  justify-self: end;
  align-self: end;
}
<div class="wrapper">
  <div class="grid">
    <div>
      R1C1
    </div>
    <div>
      R1C2
    </div>
    <div>
      R2C1
    </div>
    <div>
      R2C2
    </div>
    <div class="button">
      Button
    </div>
  </div>
</div>

Thanks in advance!

Upvotes: 2

Views: 1055

Answers (2)

Temani Afif
Temani Afif

Reputation: 272648

I don't think there is a trivial way to achieve this but you can appromxiate it like below:

.wrapper {
  display:inline-block;
  border: 1px solid blue;
  height: 300px;
  width: 200px;
  padding: 10px;
}

.grid {
  width: 100%;
  height: 100%;
  display: grid;
  grid-template-columns: 100px auto;
  grid-template-rows:repeat(100,min-content) 1fr; /* big number here*/
}
.grid *:not(:last-child) {
  margin-bottom:7px; /* replace the gap */
}

.button {
  grid-column: 1 / -1;
  grid-row: 101; /* place it at the 1fr template */
  margin:auto 0 0 auto;
}
<div class="wrapper">
  <div class="grid">
    <div>
      R1C1
    </div>
    <div>
      R1C2
    </div>
    <div>
      R2C1
    </div>
    <div>
      R2C2
    </div>
    <div class="button">
      Button
    </div>
  </div>
</div>

<div class="wrapper">
  <div class="grid">
    <div>
      R1C1
    </div>
    <div>
      R1C2
    </div>
    <div class="button">
      Button
    </div>
  </div>
</div>

<div class="wrapper">
  <div class="grid">
    <div>
      R1C1
    </div>
    <div>
      R1C2
    </div>
    <div>
      R1C1
    </div>
    <div>
      R1C2
    </div>
    <div>
      R1C1
    </div>
    <div>
      R1C2
    </div>
    <div>
      R1C1
    </div>
    <div>
      R1C2
    </div>
    <div class="button">
      Button
    </div>
  </div>
</div>

Upvotes: 1

Dan Knights
Dan Knights

Reputation: 8368

You can use the repeat function to set the first two rows to min-content:

grid-template-rows: repeat(2, min-content);

Then, use display: flex on .button and shift its content to the bottom right using justify-content and align-items:

display: flex;
align-items: flex-end;
justify-content: flex-end;

Demo: (I've added borders to demonstrate the spacing.)

.wrapper {
  border: 1px solid blue;
  height: 300px;
  width: 250px;
  padding: 10px;
}

.grid {
  width: 100%;
  height: 100%;
  display: grid;
  grid-template-columns: 100px auto;
  grid-template-rows: repeat(2, min-content);
  row-gap: 7px;
}

.grid>div {
  width: 100%;
  height: 100%;
  border: 1px solid;
}

.button {
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  grid-column: 1 / -1;
}
<div class="wrapper">
  <div class="grid">
    <div>
      R1C1
    </div>
    <div>
      R1C2
    </div>
    <div>
      R2C1
    </div>
    <div>
      R2C2
    </div>
    <div class="button">
      Button
    </div>
  </div>
</div>

Upvotes: 2

Related Questions