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.
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;
}
.lowerbar {
background-color: yellow;
height: 56px;
}
<div >
<div >
<div >
THIS TITLE HAS TO ALWAYS STAY HERE
</div>
<div >
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
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 >LOWER BAR AS TO ALWAYS STAY HERE</div>
</div>
CodePudding user response:
You just have to add position: sticky;
and top:0;
in .title
class
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;
position: sticky;
top: 0;
}
.rowcontainers {
background-color: red;
}
.lowerbar {
background-color: yellow;
height: 56px;
}
<div >
<div >
<div >
THIS TITLE HAS TO ALWAYS STAY HERE
</div>
<div >
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
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 >LOWER BAR AS TO ALWAYS STAY HERE</div>
</div>
CodePudding user response:
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 >
<div >
<div >
THIS TITLE HAS TO ALWAYS STAY HERE
</div>
<div >
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
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 >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 >
<div >
<div >
THIS TITLE HAS TO ALWAYS STAY HERE, or things get messy really really really really really really really really quickly.
</div>
<div >
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
ROWS NEED TO BE SCROLLABLE<br>
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 >LOWER BAR AS TO ALWAYS STAY HERE</div>
</div>
CodePudding user response:
You could use a combination of display: grid
on .app
and display: contents
on .main
to achieve this.
Benefits:
- Works with your dynamic heights.
- 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).
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 */
.rowcontainers::before {
content: "Start scroll test...";
display: block;
height: 300vh;
}
.rowcontainers::after {
content: "... end scroll test.";
}
<div >
<div >
<div >Header</div>
<div ></div>
</div>
<div >Footer</div>
</div>
CodePudding user response:
Change this:
.main {
background-color: orange;
overflow: scroll;
}
.rowcontainers {
background-color: red;
}
to this:
.main {
background-color: orange;
}
.rowcontainers {
background-color: red;
overflow: auto;
max-height: 400px; /*as much as you need*/
}
CodePudding user response:
<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 >
<div >
<div >
THIS TITLE HAS TO ALWAYS STAY HERE
</div>
<div >
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
ROWS NEED TO BE SCROLLABLE</br>
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 >LOWER BAR AS TO ALWAYS STAY HERE</div>
</div>
</body>
</html>
I just added this :
.rowcontainers {
background-color: red;
/* new properties below */
overflow: scroll;
height: 200px;
}
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