Dynamic multi row layout, the css grid container must take all space from its flexbox container and any extra space left over to be taken by first row

Viewed 538

I'm trying to make a css grid layout such that it will accept new grid rows and where the first row will stretch in height to take the wasted space of a flex container (in black border) as its height is increased by the user, (350px in the .flex but variable by the user in real application).

My closest solution was to use grid-template-rows: auto minmax(36px, 36px) minmax(24px, 25px) minmax(24px, 35px); but that requires to be explicit about the rows, while these dynamically change in my application.

With grid-auto-rows: minmax(min-content, max-content); the rows rendered correctly and don't need to explicitly define them but can't get the first row to take up the space taken when explicitly defining the row with grid-template-rows: and assigning auto.

Thanks in advance for your help

.flex {
  display: flex;
  flex-direction: column;
  height: 350px;
  border: solid;
  justify-content: flex-end;
}

.grid {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: minmax(100px, 207px) 1fr;
  grid-auto-rows: minmax(min-content, max-content);
}

.grid>* {
  background-color: green;
  height: 42px;
}

#dgvContainer {
  grid-column: 1/3;
}

#expander {
  grid-column: 2/3;
  background-color: white;
  justify-self: end;
}
<div class="flex">
  <div class="grid">
    <div id="dgvContainer">1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
    <div>7</div>
    <div id="expander">Expander</div>
  </div>
</div>

Fiddle:

https://codepen.io/andr-s-herrera-the-selector/pen/abJxrjy

3 Answers

Please take a look at the snippet. The added styles are marked as so.

.flex {
  display: flex;
  flex-direction: column;
  height: 350px;
  border: solid;
  justify-content: flex-end;
}

.grid {
  flex-grow: 1; /* added */
  grid-template-rows: 1fr;/* added */
  display: grid;
  grid-gap: 10px;
  grid-template-columns: minmax(100px, 207px) 1fr;
  grid-auto-rows: minmax(min-content, max-content);
}

.grid>* {
  background-color: green;
  height: 42px;
}

#dgvContainer {
    height: 100%;   /* added */
  grid-column: 1/3;
}

#expander {
  grid-column: 2/3;
  background-color: white;
  justify-self: end;
}
<div class="flex">
  <div class="grid">
    <div id="dgvContainer">1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
    <div>7</div>
    <div id="expander">Expander</div>
  </div>
</div>

Can you take a look at this and let me know if it helps. You can manipulate the height in js but you should not set a height in the css selector. https://codepen.io/indritkello/pen/ZEegzad

.flex {
  display: flex;
  flex-direction: column;
  border: solid;  
  justify-content: flex-end;
}

.grid {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: minmax(100px, 207px) 1fr;
  grid-auto-rows: minmax(min-content, max-content);
}

.grid > *:not(#dgvContainer) {
  background-color: green;
  height: 42px;
}

#dgvContainer {
    grid-column: 1/3;
    background-color: green;
    height: auto;
}

#expander {
    grid-column: 2/3;
    background-color: white;
    justify-self: end;
}

When you lift the first container out of the grid and set its bottom margin to the grid-gap, it will look the way you want it to. I don't know whether you are stuck with the structure of the html, though.

.flex {
  --gap: 10px;
  --background-colour: green;

  display: flex;
  flex-direction: column;
  height: 350px;
  border: solid;
  justify-content: flex-end;
}

.grid {
  display: grid;
  grid-gap: var(--gap);
  grid-template-columns: minmax(100px, 207px) 1fr;
  grid-auto-rows: minmax(min-content, max-content);
}

.grid>* {
  background-color: var(--background-colour);
  height: 42px;
}

#dgvContainer {
  height: 100%;
  background-color: var(--background-colour);
  margin-bottom: var(--gap);
}

#expander {
  grid-column: 2/3;
  background-color: white;
  justify-self: end;
}
<div class="flex">
  <div id="dgvContainer">1</div>
  <div class="grid">
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
    <div>7</div>
    <div id="expander">Expander</div>
  </div>
</div>

Related