Issue
I have the following HTML tree:
<html>
<body class="body">
<header>
<div class="ribbon">
<span class="ribbon-title">Template</span>
</div>
</header>
<div>
<div class="border">some content</div>
<div class="bar">other dynamic content</div>
<div class="scrollable">
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
<div>A</div>
</div>
</div>
</body>
</html>
The header has a fixed height, the div.border and the div.bar height may vary. The height of div.scrollable should fill the rest of the screen…but I am not able to.
I created a jsFiddler.
The tree structure cannot be modified and since I have a dynamic div.bar, I cannot use static heights for css calc
.
Could somebody tell me how to fix it just with CSS? No Javascript, no jQuery please.
Solution
No problem with Flexbox and some minor additions / modifications.
-
It’s important to set the full size (100%) to use the full space for flex childs.
-
Use overflow hidden for parents. Otherwise a child’s overflow auto might not work.
-
Use flex for dynamic sizes of element. Helpful for using the remaining space.
// NO JavaScript required for this solution! It's just for the demo.
// Click everywhere to change text of dynamic element `.bar`.
const barElement = document.querySelector('.bar');
const loremIpsum = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod.';
window.addEventListener('click', () => {
barElement.innerText = loremIpsum.repeat(1 + Math.random() * 4);
});
html,
body {
width: 100%;
height: 100%;
overflow: hidden;
}
body {
margin: 0px;
font-family: Arial;
display: flex;
flex-direction: column;
}
.ribbon {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 16px;
background: #494c4f;
color: #fff;
line-height: 46px;
padding: 0 20px;
}
.bar {
max-height: 150px;
overflow-y: auto;
}
main {
display: flex;
flex-direction: column;
flex: 1;
overflow: hidden;
}
.border {
padding: 0px;
}
.scrollable {
background-color: #eee;
overflow: auto;
flex: 1;
}
<html>
<body>
<header>
<div class="ribbon">
<span class="ribbon-title">Template</span>
</div>
</header>
<main>
<div class="border">some content</div>
<div class="bar">other dynamic content (click to change)</div>
<div class="scrollable">
<div>A</div>
<div>B</div>
<div>C</div>
<div>D</div>
<div>E</div>
<div>F</div>
<div>G</div>
<div>H</div>
<div>I</div>
<div>J</div>
<div>K</div>
<div>L</div>
<div>M</div>
<div>N</div>
<div>O</div>
<div>P</div>
<div>Q</div>
<div>R</div>
<div>S</div>
<div>T</div>
<div>U</div>
<div>V</div>
<div>W</div>
<div>X</div>
<div>Y</div>
<div>Z</div>
<div>0</div>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
</div>
</main>
</body>
</html>
Or JS Fiddle if you prefer it. (No guarantee of persistence. Contains the same code that you can see here.)
I just renamed your nameless div
with main
for semantic reasons. Div will also work. Just add a class for css selector.
I haven’t touched your HTML code. I only removed the class .body
from body
(useless) and div
to main
for selector. And changed the list content for better recognition. Just some optimizations. Not required. You can revert it if you want, it will still work.
The changes in summary: Your main content should be display: flex
and the scrollable list flex: 1
. With overflow: auto
and parent overflow: hidden
. The html-body should be full sized in this case. Voila.
Answered By – Dominik
This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0