空格:nowrap打破了flexbox的布局 [英] white-space: nowrap breaks flexbox layout
问题描述
我已经使用Flexbox为应用程序创建了响应式布局.该布局要求在左侧提供可折叠菜单,在中间带有标题和正文的块,在右侧提供可切换的帮助窗格(还有更多功能,但这是基本结构).
I have created a responsive layout for an app using Flexbox. The layout calls for a collapsible menu on the left, a block with a header and body in the middle and a toggleable help-pane on the right (there's more to it but that's the basic structure).
左侧菜单具有两种状态:180像素宽或80像素宽.帮助窗格是隐藏的,或占用180像素.中间的盒子占据了其余的空间.Flexbox就像一个护身符.
The left menu has two states: 180px wide or 80 px wide. The help pane is either hidden, or takes 180px. The middle box takes the rest of the space. Flexbox works like a charm.
当我使用 white-space:nowrap
进行滚动div时,麻烦就开始了.我有一堆需要在水平滚动条中显示的项目,所以我有一个包含这些项目的列表div,分别设置为 overflow:auto
和 white-space:nowrap
.
The trouble starts when I make a scrolling div using white-space: nowrap
. I have a bunch of items that need to be displayed in a horizontal scroller, so I have a list div with the items, set to overflow:auto
and white-space: nowrap
.
通常,这就像一个咒语,但是现在它破坏了我的flex布局.滚动条没有占用父(flex)div的宽度,而是使div变宽,这又将帮助窗格推到了边界之外.
Usually this works like a charm, but now it breaks my flex layout. Instead of taking the width of the parent (flex) div, the scroller makes the div wider, which in turn pushes the help-pane out of bounds.
以下小提琴说明了此问题:
The following fiddle illustrates this issue:
http://jsfiddle.net/PieBie/6y291fud/
您可以通过单击菜单栏中的切换帮助来切换帮助窗格.通过单击菜单中的列表空格切换 重新创建问题,这将切换列表的 white-space:no-wrap
CSS属性.如果帮助窗格是打开的,则可以看到它被超越了范围.
You can toggle the help-pane by clicking toggle help in the menu bar. Recreate the issue by clicking list whitespace toggle in the menu, this toggles the white-space: no-wrap
CSS property of the list. If the help-pane is open, you can see it gets pushed out of bounds.
底部列表是我想要实现的,但是我希望它是其父级的全宽度.
The bottom list is what I want to achieve, but I want it to be full width of its parent.
我可以在Chrome,Firefox,Opera,Vivaldi和Edge中重新创建该问题.Internet Explorer 11表现不错(°_°).我希望使用纯CSS解决方案(也可以选择SCSS),但是如果需要,我可以使用JS.
I can recreate the issue in Chrome, Firefox, Opera, Vivaldi and Edge. Internet Explorer 11 plays nice (°_°). I would prefer a pure CSS solution (SCSS is also an option), but if need be 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"> </div>
<div class="list-item"> </div>
<div class="list-item odd"> </div>
<div class="list-item"> </div>
<div class="list-item odd"> </div>
<div class="list-item"> </div>
<div class="list-item odd"> </div>
<div class="list-item"> </div>
<div class="list-item odd"> </div>
<div class="list-item"> </div>
<div class="list-item odd"> </div>
</div>
<hr>
<div id="secondlist">
<div class="list-item odd"> </div>
<div class="list-item"> </div>
<div class="list-item odd"> </div>
<div class="list-item"> </div>
<div class="list-item odd"> </div>
<div class="list-item"> </div>
<div class="list-item odd"> </div>
<div class="list-item"> </div>
<div class="list-item odd"> </div>
<div class="list-item"> </div>
<div class="list-item odd"> </div>
</div>
</div>
</div>
</div>
<div id="help-pane" class="visible">
- help-pane -
</div>
</div>
推荐答案
这是由默认的灵活框行为,可以防止灵活框的大小小于其内容.
This is caused by the default flex-box behaviour, which prevents flex-boxes of becoming smaller than it's contents.
此问题的解决方案是将 min-width:0
(或min-height:0(对于列而言))设置为所有父级flex-box.在这种情况下(以及小提琴):
The solution to this issue is setting min-width: 0
(or min-height: 0 for columns) to all parent flex-boxes.
In this specific case (and in the 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"> </div>
<div class="list-item"> </div>
<div class="list-item odd"> </div>
<div class="list-item"> </div>
<div class="list-item odd"> </div>
<div class="list-item"> </div>
<div class="list-item odd"> </div>
<div class="list-item"> </div>
<div class="list-item odd"> </div>
<div class="list-item"> </div>
<div class="list-item odd"> </div>
</div>
<hr>
<div id="secondlist">
<div class="list-item odd"> </div>
<div class="list-item"> </div>
<div class="list-item odd"> </div>
<div class="list-item"> </div>
<div class="list-item odd"> </div>
<div class="list-item"> </div>
<div class="list-item odd"> </div>
<div class="list-item"> </div>
<div class="list-item odd"> </div>
<div class="list-item"> </div>
<div class="list-item odd"> </div>
</div>
</div>
</div>
</div>
<div id="help-pane" class="visible">
- help-pane -
</div>
</div>
这篇关于空格:nowrap打破了flexbox的布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!