So, I need a page with a 100%-width header above and two blocks – aside and main – that fit remaining height below it in the parent block (its height – 100vh) and both lay on a horizontal baseline. Main may contain too much content so it needs to be scrollable along Y axis – only content inside it needs to be scrollable, other parts (header and sidebar) remain in their places. So I have this code (question continues after it):
body {
margin: 0;
}
.fx-a {
height: 100vh;
width: 100%;
display: flex;
flex-direction: column;
}
.header {
background: red;
}
.fx-b {
flex-grow: 1;
display: flex;
}
.aside {
background: yellow;
flex: 1;
}
.main {
background: blue;
flex: 3;
overflow-y: scroll;
}
.test {
margin-top: 100px;
}
<div class="fx-a">
<header class="header">
<h2>Title</h2>
</header>
<div class="fx-b">
<aside class="aside"></aside>
<main class="main">
<div class="test">a</div>
<div class="test">a</div>
<div class="test">a</div>
<div class="test">a</div>
<div class="test">a</div>
<div class="test">a</div>
<div class="test">a</div>
<div class="test">a</div>
<div class="test">a</div>
<div class="test">a</div>
<div class="test">a</div>
</main>
</div>
</div>
But when content in the main grows, main also grows, and sidebar does as well because it’s in the same flex box. Then, when I try to scroll, the whole page scrolls, that’s not what I need. How can it be fixed with only HTML and CSS?
P.S. I know I could set the height to header manually and then subtract it from 100vh to set the aside and main height, but I think it’s not the case – height of the header depends on content inside of it.
2
Answers
Set
overflow: hidden
on.fx-b
to force the container to limit its child:Add
height: 1px
to the container.For overflow scroll to work, there needs to be something to overflow.
Without a fixed height (or width), the container simply expands with the content, and there’s no overflow.
But with a fixed height (or width), a fixed limit is set. Once this limit is breached, an overflow condition is triggered, and the scrollbar can be activated.
Now, of course, most people want overflow scroll with dynamic lengths. That’s why this is a common problem. How to get the scrollbar without setting a height (or width)?
The answer is actually quite simple with the advent of flexbox.
Give the browser what it wants: a fixed length.
But make it meaningless to the layout, using
flex-grow
for the actual height.In other words:
height: 1px; flex-grow: 1