You could use a combination of display: grid on .app and display: contents on .main to achieve this.
Benefits:
Works with your dynamic heights without having to explicitly specify them.
Stretches to use the whole viewport whether .rowcontainers has enough content or not.
Doesn’t make the title look like it’s part of the scrollable content (as in the position: sticky solution).
/* Just ignore this script for toggling overflow content by clicking the button */ { const b = document.getElementById("togglescrolltest"), t = document.getElementById("scrolltest"), c = { block: ["none", "add scroll test"], none: ["block", "remove scroll test"] }; b.addEventListener("click", e => { const d = window.getComputedStyle(t).display; [t.style.display, b.textContent] = c[d]; });}
body {
margin: 0;
}
.app {
height: 100vh;
/* grid stuff: */
display: grid;
grid-template-columns: auto;
grid-template-rows: min-content auto min-content;
}
.main {
/* skip this tier in the DOM hierarchy for styling */
display: contents;
}
.title {
background: #00F;
}
.rowcontainers {
background: #F00;
/* scroll when necessary: */
overflow: auto;
}
.lowerbar {
background: #FF0;
height: 56px;
}
/* test scrolling without extra markup */
#scrolltest {
margin-top: 300vh;
}
<div class="app">
<div class="main">
<div class="title">
THIS TITLE HAS TO ALWAYS STAY HERE
</div>
<div class="rowcontainers">
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
</div>
</div>
<div class="lowerbar">LOWER BAR AS TO ALWAYS STAY HERE</div>
</div>
Solution 3 :
Here’s a solution that uses calc to figure out the maximum height of the rowcontianer element. You had already indicated you wanted 100vh as the height of the body, and 56px as the height of the lowerbar. I added a line-height: 1.4rem for the title element.
This code will work as long as title remains a single line of text, and lowerbar remains 56px.
body {
height: 100vh;
margin: 0;
background-color: white;
}
.app {
margin: auto;
max-height: 100%;
max-width: 600px;
background-color: black;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.main {
background-color: orange;
}
.title {
background-color: blue;
line-height: 1.4rem;
}
.rowcontainers {
background-color: red;
max-height: calc(100vh - 56px - 1.4rem); /* 56px (height of lowerbar) 1.4rem (line-height of title) Consider using flexbox methods if you think title may wrap to two lines or lowerbar might grow. */
overflow: scroll;
}
.lowerbar {
background-color: yellow;
height: 56px;
}
<div class="app">
<div class="main">
<div class="title">
THIS TITLE HAS TO ALWAYS STAY HERE
</div>
<div class="rowcontainers">
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
</div>
</div>
<div class="lowerbar">LOWER BAR AS TO ALWAYS STAY HERE</div>
</div>
A more foolproof way of doing this would be with flexbox:
body {
height: 100vh;
margin: 0;
background-color: white;
display: flex;
flex-flow: column nowrap;
}
.app {
/* Added flex-grow and flex-basis: 100% so that app starts off at 100% height */
flex: 1 0 100%;
margin: 0 auto;
max-width: 600px;
background-color: black;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.main {
/* Added flex-grow and flex-basis: calc(100vh - 56px) so that main starts off
at 100% height of body less the height of lowerbar. Set the max-height to
the same so that it doesn't grow too large. Could also set flex-grow to 0.*/
flex: 1 0 calc(100vh - 56px);
max-height: calc(100vh - 56px);
background-color: orange;
display: flex;
flex-flow: column nowrap;
}
.title {
background-color: blue;
/* The basis is one line, but it should expand as needed */
flex: 1 0 1.4rem;
}
.rowcontainers {
background-color: red;
/* flex-grow is set to 0 so that it doesn't go beyond its container and keeps
its initial height, allowing scroll to work. */
flex: 0 0 100%;
overflow: scroll;
}
.lowerbar {
background-color: yellow;
flex: 0 0 56px;
}
<div class="app">
<div class="main">
<div class="title">
THIS TITLE HAS TO ALWAYS STAY HERE, or things get messy really really really really really really really really quickly.
</div>
<div class="rowcontainers">
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
</div>
</div>
<div class="lowerbar">LOWER BAR AS TO ALWAYS STAY HERE</div>
</div>
.main {
background-color: orange;
}
.rowcontainers {
background-color: red;
overflow: auto;
max-height: 400px; /*as much as you need*/
}
Solution 5 :
<html>
<head>
<style>
body {
height: 100vh;
margin: 0;
background-color: white;
}
.app {
margin: auto;
max-height: 100%;
max-width: 600px;
background-color: black;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.main {
background-color: orange;
overflow: scroll;
}
.title {
background-color: blue;
}
.rowcontainers {
background-color: red;
/* new properties below */
overflow: scroll;
height: 300px;
}
.lowerbar {
background-color: yellow;
height: 56px;
}
</style>
</head>
<body>
<div class="app">
<div class="main">
<div class="title">
THIS TITLE HAS TO ALWAYS STAY HERE
</div>
<div class="rowcontainers">
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
</div>
</div>
<div class="lowerbar">LOWER BAR AS TO ALWAYS STAY HERE</div>
</div>
</body>
</html>
As long as the browser can detect an overflow, it should work.
So, height: auto; won’t work
If you can’t set any height, well.. sorry I’m out of ideas
Problem :
I’ve got a setup similar to the snippet of code below. My goal is to keep the “blue” and “yellow” divs fixed in position, while the “blue” one if it contains more rows than the available space has to be scrollable.
Due to the nature of the code, I cannot change the position of the divs in the body nor hardcode any height (since both the title and the bar height are computed at runtime).
I have to achieve this only by changing the CSS.
With the current solution, I’m able to make the yellow div stay in place while I can’t also make the blue one stay there instead of following the scrolling.
<div class="app">
<div class="main">
<div class="title">
THIS TITLE HAS TO ALWAYS STAY HERE
</div>
<div class="rowcontainers">
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
</div>
</div>
<div class="lowerbar">LOWER BAR AS TO ALWAYS STAY HERE</div>
</div>
Comments
Comment posted by Heretic Monkey
Why not just make
Comment posted by Luca Reccia
That’s a good question @HereticMonkey, when I try to do that the main takes as height the one required by the children divs (if it’s more than the screen height then it will make the lower bar disappear under the screen)
Comment posted by Luca Reccia
Hey @Heretic Monkey, as I said I cannot hardcode credentials, and your solution using calc is hardcoding them
Comment posted by Luca Reccia
Hey man, thanks for your time, as I said I cannot hardcode any height so this is not a viable solution for me
Comment posted by Abdul Raheem Dumrai
Can you just share a screenshot so I can clearly see what do you want. Because as far as I understand you want the blue and yellow to stay on their positions and the red one to be scroll able right? And do you want to use position: fixed for blue and yellow? Thanks for the comment brother!
Comment posted by Luca Reccia
Hey Benjamin, you gave a fixed height to the container, this does not work well with various devices.