问题
I am trying to make a page which consists of a header, a left nav and some content.
I would like the left nav and the content to reach up to the bottom of the viewport, so that no scroll bar appears for the whole page.
However both the left nav and the content can be very large, so I would like each of them to have a scroll for overflow-y
.
I have tried using blocks/floats but didn't manage to achieve my intended result.
I saw that flex has the flex-grow
which seemed to offer a solution, however I haven't managed to make it work.
In the fiddle below I have attempted to have a column flexbox for the header and remaining site, and a row flexbox for the left nav and content, however these grow beyond the height of the viewport.
https://jsfiddle.net/ph8qnfky/4/
body {
height: 100%;
margin: 0;
}
.viewportDiv {
display: flex;
flex-flow: column;
height: 100%;
}
.header{
background-color: yellow;
height: 100px;
min-height: 100px;
}
.remainingDiv{
background-color: red;
flex-grow: 1;
}
.mainSite {
display: flex;
flex-direction: row;
flex-grow: 1;
/* max-height: 100px; */
}
.leftNav{
background-color: green;
width: 200px;
overflow-y: scroll;
}
.content {
background-color: grey;
overflow-y: scroll;
}
<div class="viewportDiv">
<div class="header">Site header</div>
<div class="remainingDiv">
<div class="mainSite">
<div class="leftNav">
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
</div>
<div class="content">
Lorem ipsum dolor sit amet, <br/> consectetur adipiscing elit. <br/>Aliquam vel ullamcorper ligula. Vestibulum nibh arcu, mollis in commodo ut, tristique sed sapien. Cras elementum facilisis consequat. Suspendisse eleifend gravida arcu, a rhoncus mi placerat at. <br/>Cras et vestibulum nulla, at vestibulum arcu. Pellentesque at aliquam turpis. Integer consequat tristique diam scelerisque consequat. <br/>Nullam mattis condimentum diam, sed tincidunt lacus iaculis a. Sed eu ex arcu. <br/>Nullam libero enim, venenatis quis vehicula id, fermentum vitae sapien. Praesent vehicula est id orci rhoncus, <br/>dignissim sodales risus commodo.
Lorem ipsum dolor sit amet, <br/> consectetur adipiscing elit. <br/>Aliquam vel ullamcorper ligula. Vestibulum nibh arcu, mollis in commodo ut, tristique sed sapien. Cras elementum facilisis consequat. Suspendisse eleifend gravida arcu, a rhoncus mi placerat at. <br/>Cras et vestibulum nulla, at vestibulum arcu. Pellentesque at aliquam turpis. Integer consequat tristique diam scelerisque consequat. <br/>Nullam mattis condimentum diam, sed tincidunt lacus iaculis a. Sed eu ex arcu. <br/>Nullam libero enim, venenatis quis vehicula id, fermentum vitae sapien. Praesent vehicula est id orci rhoncus, <br/>dignissim sodales risus commodo.
Lorem ipsum dolor sit amet, <br/> consectetur adipiscing elit. <br/>Aliquam vel ullamcorper ligula. Vestibulum nibh arcu, mollis in commodo ut, tristique sed sapien. Cras elementum facilisis consequat. Suspendisse eleifend gravida arcu, a rhoncus mi placerat at. <br/>Cras et vestibulum nulla, at vestibulum arcu. Pellentesque at aliquam turpis. Integer consequat tristique diam scelerisque consequat. <br/>Nullam mattis condimentum diam, sed tincidunt lacus iaculis a. Sed eu ex arcu. <br/>Nullam libero enim, venenatis quis vehicula id, fermentum vitae sapien. Praesent vehicula est id orci rhoncus, <br/>dignissim sodales risus commodo.
Lorem ipsum dolor sit amet, <br/> consectetur adipiscing elit. <br/>Aliquam vel ullamcorper ligula. Vestibulum nibh arcu, mollis in commodo ut, tristique sed sapien. Cras elementum facilisis consequat. Suspendisse eleifend gravida arcu, a rhoncus mi placerat at. <br/>Cras et vestibulum nulla, at vestibulum arcu. Pellentesque at aliquam turpis. Integer consequat tristique diam scelerisque consequat. <br/>Nullam mattis condimentum diam, sed tincidunt lacus iaculis a. Sed eu ex arcu. <br/>Nullam libero enim, venenatis quis vehicula id, fermentum vitae sapien. Praesent vehicula est id orci rhoncus, <br/>dignissim sodales risus commodo.
</div>
</div>
</div>
</div>
I would like to achieve both leftNav and content to cut off at viewport end and have their scroll bars enabled.
I am trying to solve this with flex as it seemed to be a good fit, but if there is a non-flex solution involving only css I would not have a problem using it.
Best regards
回答1:
For the overflow
property to work reliably across browsers it needs to have a fixed height or width. Flex properties don't always trigger an overflow condition. flex-grow
almost never works because it doesn't set a length, it simply consumes free space, and overflow
doesn't pay attention to that.
From MDN:
In order for
overflow
to have an effect, the block-level container must have either a set height (height
ormax-height
) orwhite-space
set tonowrap
.
In this case, because the layout occupies the height of the viewport (height: 100vh
), and there are only two siblings, with one (the .header
) having a fixed height of 100px, the solution is relatively simple.
Set the other sibling (.remainingDiv
) to height: calc(100vh - 100px)
, then give the overflowing children height: 100%
. This will generate the scrollbars you want.
.viewportDiv {
display: flex;
flex-flow: column;
height: 100vh;
}
.header {
background-color: yellow;
flex: 0 0 100px; /* more efficient than original rules (disables flex-shrink) */
}
.remainingDiv {
background-color: red;
flex: 0 0 calc(100vh - 100px); /* occupy remaining height */
height: calc(100vh - 100px); /* fallback, as some browsers may not accept
flex-basis in this case */
display: flex; /* make children occupy full height */
min-height: 0; /* patch for Firefox */
}
.mainSite {
display: flex;
height: 100%; /* take height of parent */
}
.leftNav {
background-color: green;
flex: 0 0 200px; /* more efficient than original rule (disables flex-shrink) */
overflow-y: scroll;
}
.content {
background-color: grey;
overflow-y: scroll;
}
body {
margin: 0;
}
<div class="viewportDiv">
<div class="header">Site header</div>
<div class="remainingDiv">
<div class="mainSite">
<div class="leftNav">
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
<div>item</div>
</div>
<div class="content">
Lorem ipsum dolor sit amet, <br/> consectetur adipiscing elit. <br/>Aliquam vel ullamcorper ligula. Vestibulum nibh arcu, mollis in commodo ut, tristique sed sapien. Cras elementum facilisis consequat. Suspendisse eleifend gravida arcu, a rhoncus
mi placerat at. <br/>Cras et vestibulum nulla, at vestibulum arcu. Pellentesque at aliquam turpis. Integer consequat tristique diam scelerisque consequat. <br/>Nullam mattis condimentum diam, sed tincidunt lacus iaculis a. Sed eu ex arcu. <br/>Nullam
libero enim, venenatis quis vehicula id, fermentum vitae sapien. Praesent vehicula est id orci rhoncus, <br/>dignissim sodales risus commodo. Lorem ipsum dolor sit amet, <br/> consectetur adipiscing elit. <br/>Aliquam vel ullamcorper ligula. Vestibulum
nibh arcu, mollis in commodo ut, tristique sed sapien. Cras elementum facilisis consequat. Suspendisse eleifend gravida arcu, a rhoncus mi placerat at. <br/>Cras et vestibulum nulla, at vestibulum arcu. Pellentesque at aliquam turpis. Integer
consequat tristique diam scelerisque consequat. <br/>Nullam mattis condimentum diam, sed tincidunt lacus iaculis a. Sed eu ex arcu. <br/>Nullam libero enim, venenatis quis vehicula id, fermentum vitae sapien. Praesent vehicula est id orci rhoncus,
<br/>dignissim sodales risus commodo. Lorem ipsum dolor sit amet, <br/> consectetur adipiscing elit. <br/>Aliquam vel ullamcorper ligula. Vestibulum nibh arcu, mollis in commodo ut, tristique sed sapien. Cras elementum facilisis consequat. Suspendisse
eleifend gravida arcu, a rhoncus mi placerat at. <br/>Cras et vestibulum nulla, at vestibulum arcu. Pellentesque at aliquam turpis. Integer consequat tristique diam scelerisque consequat. <br/>Nullam mattis condimentum diam, sed tincidunt lacus
iaculis a. Sed eu ex arcu. <br/>Nullam libero enim, venenatis quis vehicula id, fermentum vitae sapien. Praesent vehicula est id orci rhoncus, <br/>dignissim sodales risus commodo. Lorem ipsum dolor sit amet, <br/> consectetur adipiscing elit.
<br/>Aliquam vel ullamcorper ligula. Vestibulum nibh arcu, mollis in commodo ut, tristique sed sapien. Cras elementum facilisis consequat. Suspendisse eleifend gravida arcu, a rhoncus mi placerat at. <br/>Cras et vestibulum nulla, at vestibulum
arcu. Pellentesque at aliquam turpis. Integer consequat tristique diam scelerisque consequat. <br/>Nullam mattis condimentum diam, sed tincidunt lacus iaculis a. Sed eu ex arcu. <br/>Nullam libero enim, venenatis quis vehicula id, fermentum vitae
sapien. Praesent vehicula est id orci rhoncus, <br/>dignissim sodales risus commodo.
</div>
</div>
</div>
</div>
revised fiddle
回答2:
Add max-height: 100vh;
to .mainSite
, so it would be something like this:
.mainSite {
display: flex;
flex-direction: row;
flex-grow: 1;
max-height: 100vh;
}
CSS Units
来源:https://stackoverflow.com/questions/57747410/set-vertical-scrollbar-on-flex-children-not-whole-page