Is it possible to get the stretch behavior of display: flex
when min-content
would not fill the page, but still have good scrolling behavior if min-content
is larger than the page size?
Essentially if the behavior second code snippet doesn't fill the page, I want the behavior of the first code snippet.
document.addEventListener("DOMContentLoaded", () => {
document.querySelector(".footer > input").addEventListener("change", (event) => {
for (d of document.querySelectorAll(".content > div")) {
d.style.height = ((event.target.value < 0.01) ? "100%" : (event.target.value + 'rem'));
}
});
});
* {
margin: 0.5rem;
}
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
justify-items: stretch;
align-items: stretch;
background-color: grey;
}
.content {
height: 100%;
display: flex;
flex-direction: column;
justify-items: stretch;
align-items: stretch;
background-color: blue;
}
.content>div {
height: 100%;
min-height: 1rem;
background-color: gold;
}
.footer {
height: 2rem;
min-height: 2rem;
flex: 0 0 1;
display: flex;
justify-content: center;
align-items: center;
background-color: green;
}
<body>
<div class="content">
<div></div>
<div></div>
<div></div>
</div>
<div class="footer">
<input type="number" value=0 min=0>
</div>
</body>
document.addEventListener("DOMContentLoaded", () => {
document.querySelector(".footer > input").addEventListener("change", (event) => {
for (d of document.querySelectorAll(".content > div")) {
d.style.height = event.target.value + 'rem';
}
});
});
* {
margin: 0.5rem;
}
html, body {
width: 100%;
height: min-content;
margin: 0;
padding: 0;
}
body {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
justify-items: stretch;
align-items: stretch;
background-color: grey;
}
.content {
height: min-content;
display: flex;
flex-direction: column;
justify-items: stretch;
align-items: stretch;
background-color: blue;
}
.content > div {
height: 6rem;
min-height: 1rem;
background-color: gold;
}
.footer {
height: 2rem;
min-height: 2rem;
flex: 0 0 1;
display: flex;
justify-content: center;
align-items: center;
background-color: green;
}
<body>
<div class="content">
<div></div>
<div></div>
<div></div>
</div>
<div class="footer">
<input type="number" value=1 min=0>
</div>
</body>
Edit: Added input box to make the behavior easier to see. If the gold boxes are too large in the first snippet than you can't scroll to see all of the footer. In the second snippet, the blue and gold boxes will never stretch to fill the available space.
I was able to get it working. I think the key was to use min-height: 100vh
instead of height: 100vh
as well as using flex-grow: 1
. I tried flex: 1
before making the OP, but that didn't work (I probably need to read more about flex
since it's apparently preferred to use flex
instead of flex-*
).
document.addEventListener("DOMContentLoaded", () => {
document.querySelector("#footer > input").addEventListener("change", (event) => {
for (d of document.querySelectorAll(".content > div")) {
d.style.height = event.target.value + 'rem';
}
});
});
body {
margin: 0;
padding: 0;
}
.container {
width: 100%;
min-height: 100vh;
padding: 0.5rem;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-items: stretch;
background-color: gray;
}
.content {
padding: 0.5rem;
flex-grow: 1;
display: flex;
flex-direction: column;
justify-items: stretch;
background-color: blue;
}
.content div {
height: 2rem;
flex-grow: 1;
border: solid;
background-color: gold;
}
.footer {
height: 2rem;
background-color: green;
display: flex;
justify-content: center;
align-items: center;
}
.footer>input {
height: min-content;
}
<div class="container">
<div class="content">
<div></div>
<div></div>
<div></div>
</div>
<div id="footer" class="footer">
<input type="number" value=1 min=0>
</div>
</div>