White-space: nowrap breaks flexbox layout

I created a responsive layout for the application using Flexbox. The layout requires a collapsible menu on the left, a block with a title and a body in the middle, and a switchable help panel on the right (there is more, but the main structure).

The left menu has two states: 180 pixels wide or 80 pixels wide. The help panel is either hidden or occupies 180 pixels. The middle drawer occupies the rest of the space. Flexbox works like a charm.

The problem starts when I scroll through the div using white-space: nowrap . I have a bunch of elements that need to be displayed in a horizontal scroller, so I have a list of divs with elements set to overflow:auto and white-space: nowrap .

This usually works like a charm, but now it breaks my flexible layout. Instead of taking the width of the parent (flex) div, the scroller makes the div wider, which in turn pushes the help panel out.


The following script illustrates this problem:

http://jsfiddle.net/PieBie/6y291fud/

You can switch the help panel by clicking the "Help" button in the menu bar. To fix the problem by clicking the space list switch in the menu, this toggles the white-space: no-wrap CSS property in the list. If the help panel is open, you can see that it is being pushed out of bounds.

The bottom list is what I want to achieve, but I want it to be the full width of its parent.

I can recreate the problem in Chrome, Firefox, Opera, Vivaldi and Edge. Internet Explorer 11 plays well (° _ °). I would prefer a pure CSS solution (SCSS is also an option), but if necessary, I can use JS.


 $('#nav-toggle').on('click',function(){ $(this).parent().toggleClass('collapsed'); }); $('#help-toggle').on('click',function(){ $('#help-pane').toggleClass('visible'); }); $('#list-toggle').on('click',function(){ $('#list').toggleClass('nowrap'); }); 
 body,html{width:100%;height:100%;overflow:hidden;} #body{ display:flex; flex-flow:row nowrap; position:absolute; top:0; left:0; margin:0; padding:0; width:100%; height:100%; background-color:#abc; overflow:hidden; } #shell{ flex: 1 1 auto; display:flex; flex-flow:row nowrap; position:relative; width:100%; min-height:100%; } #left{ flex: 0 0 180px; min-height:100%; min-width: 0; background:lightblue; } #left.collapsed{ flex: 0 0 80px; } #mid{ flex: 1 1 auto; min-height:100%; min-width: 0; display:flex; flex-flow:column nowrap; align-items:stretch; align-content:stretch; position:relative; width:100%; min-height:100vh; min-width: 0; background:purple; } #mid-top{ flex: 0 0 auto; min-height:100px; background:green; } #mid-bottom{ min-height:calc(100% - 100px); flex: 1 1 auto; background:lightgreen; } #list{ overflow: auto; width: 100%; max-width: 100%; } #list.nowrap{ white-space: nowrap; } #secondlist{ overflow: auto; max-width: 250px; white-space: nowrap; } .list-item{ display: inline-block; width: 50px; height: 50px; margin: 2px; background: purple; } .list-item.odd{ background: violet; } #help-pane{ display:none; flex: 0 0 0px; background:red; } #help-pane.visible{ display:inherit; flex:0 0 180px; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="body"> <div id="shell"> <div id="left"> <div id="nav"> - menu - </div> <div id="help-toggle"> help toggle </div> <div id="nav-toggle"> nav toggle </div> <div id="list-toggle"> list whitespace toggle </div> </div> <div id="mid"> <div id="mid-top"> - mid top - </div> <div id="mid-bottom"> - mid bottom- <br><br> <div id="list"> <div class="list-item odd">&nbsp;</div> <div class="list-item">&nbsp;</div> <div class="list-item odd">&nbsp;</div> <div class="list-item">&nbsp;</div> <div class="list-item odd">&nbsp;</div> <div class="list-item">&nbsp;</div> <div class="list-item odd">&nbsp;</div> <div class="list-item">&nbsp;</div> <div class="list-item odd">&nbsp;</div> <div class="list-item">&nbsp;</div> <div class="list-item odd">&nbsp;</div> </div> <hr> <div id="secondlist"> <div class="list-item odd">&nbsp;</div> <div class="list-item">&nbsp;</div> <div class="list-item odd">&nbsp;</div> <div class="list-item">&nbsp;</div> <div class="list-item odd">&nbsp;</div> <div class="list-item">&nbsp;</div> <div class="list-item odd">&nbsp;</div> <div class="list-item">&nbsp;</div> <div class="list-item odd">&nbsp;</div> <div class="list-item">&nbsp;</div> <div class="list-item odd">&nbsp;</div> </div> </div> </div> </div> <div id="help-pane" class="visible"> - help-pane - </div> </div> 
+8
html css flexbox whitespace webkit
source share
1 answer

This is caused by default by the flexible field , which prevents the flexible boxes from being reduced in size than their contents.

The solution to this problem is to set min-width: 0 (or min-height: 0 for columns) to all parent flexible windows. In this particular case (and in fiddle ):

 #shell{ flex: 1 1 auto; display:flex; flex-flow:row nowrap; position:relative; width:100%; min-height:100%; min-width: 0; /* this one right here does it!*/ } 

 $('#nav-toggle').on('click',function(){ $(this).parent().toggleClass('collapsed'); }); $('#help-toggle').on('click',function(){ $('#help-pane').toggleClass('visible'); }); $('#list-toggle').on('click',function(){ $('#list').toggleClass('nowrap'); }); 
 body,html{width:100%;height:100%;overflow:hidden;} #body{ display:flex; flex-flow:row nowrap; position:absolute; top:0; left:0; margin:0; padding:0; width:100%; height:100%; background-color:#abc; overflow:hidden; } #shell{ flex: 1 1 auto; display:flex; flex-flow:row nowrap; position:relative; width:100%; min-height:100%; min-width: 0; } #left{ flex: 0 0 180px; min-height:100%; min-width: 0; background:lightblue; } #left.collapsed{ flex: 0 0 80px; } #mid{ flex: 1 1 auto; min-height:100%; min-width: 0; display:flex; flex-flow:column nowrap; align-items:stretch; align-content:stretch; position:relative; width:100%; min-height:100vh; min-width: 0; background:purple; } #mid-top{ flex: 0 0 auto; min-height:100px; background:green; } #mid-bottom{ min-height:calc(100% - 100px); flex: 1 1 auto; background:lightgreen; } #list{ overflow: auto; width: 100%; max-width: 100%; } #list.nowrap{ white-space: nowrap; } #secondlist{ overflow: auto; max-width: 250px; white-space: nowrap; } .list-item{ display: inline-block; width: 50px; height: 50px; margin: 2px; background: purple; } .list-item.odd{ background: violet; } #help-pane{ display:none; flex: 0 0 0px; background:red; } #help-pane.visible{ display:inherit; flex:0 0 180px; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="body"> <div id="shell"> <div id="left"> <div id="nav"> - menu - </div> <div id="help-toggle"> help toggle </div> <div id="nav-toggle"> nav toggle </div> <div id="list-toggle"> list whitespace toggle </div> </div> <div id="mid"> <div id="mid-top"> - mid top - </div> <div id="mid-bottom"> - mid bottom- <br><br> <div id="list"> <div class="list-item odd">&nbsp;</div> <div class="list-item">&nbsp;</div> <div class="list-item odd">&nbsp;</div> <div class="list-item">&nbsp;</div> <div class="list-item odd">&nbsp;</div> <div class="list-item">&nbsp;</div> <div class="list-item odd">&nbsp;</div> <div class="list-item">&nbsp;</div> <div class="list-item odd">&nbsp;</div> <div class="list-item">&nbsp;</div> <div class="list-item odd">&nbsp;</div> </div> <hr> <div id="secondlist"> <div class="list-item odd">&nbsp;</div> <div class="list-item">&nbsp;</div> <div class="list-item odd">&nbsp;</div> <div class="list-item">&nbsp;</div> <div class="list-item odd">&nbsp;</div> <div class="list-item">&nbsp;</div> <div class="list-item odd">&nbsp;</div> <div class="list-item">&nbsp;</div> <div class="list-item odd">&nbsp;</div> <div class="list-item">&nbsp;</div> <div class="list-item odd">&nbsp;</div> </div> </div> </div> </div> <div id="help-pane" class="visible"> - help-pane - </div> </div> 
+16
source share

All Articles