In the snippet below, I have 5 cells named a
through e
. a
and b
should be side by side and as tall as possible with a fixed width. c
should be below them, shrinking its height as much as possible and matching the width of a
and b
combined. d
and e
should be on the right, stacked with d
on top, taking all available width with e
having a fixed height and letting d
take up as much height as possible.
I do not want the heights of c
and e
to be at all related. Thus, I have placed d
and e
in a nested grid (brilliantly named de
). I expect that when I set the height of e
to some value, it should become that height, and d
should shrink or grow as needed, and everything else should stay the same. However, when I change the height of e
, c
also changes its height.
Why in the world is my nested grid effecting its parent, and how to I prevent it?
Here is the snippet, and a fiddle just in case. You can change the height of e
by adjusting the value if the input.
let e = document.getElementById('e')
let heightInput = document.querySelector('#controls input')
heightInput.addEventListener('input', function() {
e.style.height = heightInput.value + 'px'
})
html, body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#controls {
height: 25px;
padding: 5px;
}
#grid {
background: orange;
width: 100%;
height: calc(100% - 35px);
display: grid;
grid-template-columns: min-content min-content auto;
grid-template-rows: auto min-content;
grid-template-areas:
'a b de'
'c c de';
}
#a {
background: red;
grid-area: a;
width: 30px;
}
#b {
background: blue;
grid-area: b;
width: 30px;
}
#c {
background: green;
grid-area: c;
}
#de {
background: purple;
grid-area: de;
display: grid;
grid-template-rows: auto min-content;
grid-template-areas:
'd'
'e';
}
#d {
background: grey;
grid-area: d;
}
#e {
background: yellow;
grid-area: e;
height: 30px;
}
<body>
<div id="controls">
Set height of e in px <input type="number" value="30" />
</div>
<div id="grid">
<div id="a">a</div>
<div id="b">b</div>
<div id="c">c</div>
<div id="de">
<div id="d">d</div>
<div id="e">e</div>
</div>
</div>
</body>
Actually I don't have an accurate explanation but this is due to the computation of min-content
. Instead of it you can use the combination of 1fr
and auto
let e = document.getElementById('e')
let heightInput = document.querySelector('#controls input')
heightInput.addEventListener('input', function() {
e.style.height = heightInput.value + 'px'
})
html, body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#controls {
height: 25px;
padding: 5px;
}
#grid {
background: orange;
width: 100%;
height: calc(100% - 35px);
display: grid;
grid-template-columns: min-content min-content auto;
grid-template-rows: 1fr auto; /* updated this */
grid-template-areas:
'a b de'
'c c de';
}
#a {
background: red;
grid-area: a;
width: 30px;
}
#b {
background: blue;
grid-area: b;
width: 30px;
}
#c {
background: green;
grid-area: c;
}
#de {
background: purple;
grid-area: de;
display: grid;
grid-template-rows: 1fr auto; /* updated this too but not mandatory */
grid-template-areas:
'd'
'e';
}
#d {
background: grey;
grid-area: d;
}
#e {
background: yellow;
grid-area: e;
height: 30px;
}
<body>
<div id="controls">
Set height of e in px <input type="number" value="30" />
</div>
<div id="grid">
<div id="a">a</div>
<div id="b">b</div>
<div id="c">c</div>
<div id="de">
<div id="d">d</div>
<div id="e">e</div>
</div>
</div>
</body>