How can I make the nested flexbox element shrink and display the scroll bar when resizing the viewport?

I am building a layout using flexbox and it is pretty simple overall. There are three parts to the view: the navigation bar at the top, the sidebar on the left and the content area that fills the remaining space. The navigation bar has a fixed height and the sidebar has a fixed width.

In addition, the sidebar and content areas must scroll individually. If the content in the sidebar overflows, it should create a sidebar specific scrollbar. The same thing happens with the presentation of content. It is important to note that this means that the overall viewport should never scroll: it should remain static (only elements should scroll).

Building this layout is very simple with flexbox:

html, body { height: 100%; width: 100%; } body { margin: 0; } #root { display: flex; height: 100%; } #frame { display: flex; flex: 1; flex-direction: column; } #navigation-bar { background-color: #bab; display: flex; height: 70px; overflow: hidden; } #main { display: flex; flex: 1; } #left-bar { background-color: #aaa; overflow: auto; width: 250px; } #content { background-color: #ccc; flex: 1; } 
 <div id="root"> <div id="frame"> <div id="navigation-bar"> <h1>Website Name</h1> </div> <div id="main"> <div id="left-bar"> <h1>Some content</h1> <h1>Some content</h1> <h1>Some content</h1> <h1>Some content</h1> <h1>Some content</h1> <h1>Some content</h1> <h1>Some content</h1> <h1>Some content</h1> <h1>Some content</h1> </div> <div id="content"> </div> </div> </div> </div> 

However, note that the sidebar does not scroll separately. Instead, the entire viewport expands and scrolls. Interestingly, what I'm trying to achieve works correctly without nesting - if I remove the navigation bar, the sidebar scrolls independently.

How can I prevent flexbox from stretching itself to contain its contents so that the scrollbar that is specific to the element is displayed, and not the scrollbar in the viewport?

+4
source share
1 answer

Add this:

 #main { min-height: 0; flex: 1 1 0; } 

 html, body { height: 100%; width: 100%; } body { margin: 0; } #root { display: flex; height: 100%; } #frame { display: flex; flex: 1; flex-direction: column; } #navigation-bar { background-color: #bab; display: flex; height: 70px; overflow: hidden; } #main { display: flex; flex: 1 1 0; min-height: 0; } #left-bar { background-color: #aaa; overflow: auto; width: 250px; } #content { background-color: #ccc; flex: 1; } 
 <div id="root"> <div id="frame"> <div id="navigation-bar"> <h1>Website Name</h1> </div> <div id="main"> <div id="left-bar"> <h1>Some content</h1> <h1>Some content</h1> <h1>Some content</h1> <h1>Some content</h1> <h1>Some content</h1> <h1>Some content</h1> <h1>Some content</h1> <h1>Some content</h1> <h1>Some content</h1> </div> <div id="content"></div> </div> </div> </div> 

You need min-height: 0 because, as explained in How can I get the behavior of FF 33.x Flexbox in FF 34.x? , w920> changes the initial value of min-height :

4.5 Minimum Flex Element Size

To provide a more reasonable default minimum size for flex items , this specification introduces a new auto value as the initial value of the min-width and min-height properties defined in CSS 2.1.

I also added flex: 1 1 0 because flex: 1 becomes flex: 1 1 0% , but 0% doesn’t work in Chrome in the column layout. But 0 works well.

+11
source

All Articles