- 首页
- 前端开发
- 空白:nowrap 打破了 flexbox 布局
空白:nowrap 打破了 flexbox 布局
[英] white-space: nowrap breaks flexbox layout
本文介绍了空白:nowrap 打破了 flexbox 布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我使用 Flexbox 为应用程序创建了响应式布局.布局要求左侧有一个可折叠的菜单,中间有一个标题和正文的块,右侧有一个可切换的帮助窗格(还有更多内容,但这是基本结构).
左侧菜单有两种状态:180 像素宽或 80 像素宽.帮助窗格要么隐藏,要么占用 180 像素.中间的盒子占据了其余的空间.Flexbox 就像一个魅力.
当我使用 white-space: nowrap
制作滚动 div 时,麻烦就开始了.我有一堆需要在水平滚动条中显示的项目,所以我有一个包含项目的列表 div,设置为 overflow:auto
和 white-space: nowrap
.
通常这就像一个魅力,但现在它打破了我的 flex 布局.滚动条不会占用父 (flex) div 的宽度,而是使 div 更宽,这反过来又将帮助窗格推到了边界之外.
<小时>
以下小提琴说明了这个问题:
http://jsfiddle.net/PieBie/6y291fud/
您可以通过单击菜单栏中的切换帮助来切换帮助窗格.通过单击菜单中的列表空白切换重新创建问题,这将切换列表的 white-space: no-wrap
CSS 属性.如果帮助窗格处于打开状态,您可以看到它被推到了边界之外.
底部列表是我想要实现的,但我希望它是其父级的全宽.
我可以在 Chrome、Firefox、Opera、Vivaldi 和 Edge 中重现该问题.Internet Explorer 11 运行良好 (°_°).我更喜欢纯 CSS 解决方案(SCSS 也是一种选择),但如果需要,我可以使用 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;}#身体{显示:弹性;flex-flow:row nowrap;位置:绝对;顶部:0;左:0;保证金:0;填充:0;宽度:100%;高度:100%;背景色:#abc;溢出:隐藏;}#壳{弹性:1 1 自动;显示:弹性;flex-flow:row nowrap;位置:相对;宽度:100%;最小高度:100%;}#剩下{弹性:0 0 180px;最小高度:100%;最小宽度:0;背景:浅蓝色;}#left.collapsed{弹性:0 0 80px;}#中{弹性:1 1 自动;最小高度:100%;最小宽度:0;显示:弹性;flex-flow:column nowrap;对齐项目:拉伸;对齐内容:拉伸;位置:相对;宽度:100%;最小高度:100vh;最小宽度:0;背景:紫色;}#中上{弹性:0 0 自动;最小高度:100px;背景:绿色;}#中底{最小高度:计算(100% - 100px);弹性:1 1 自动;背景:浅绿色;}#列表{溢出:自动;宽度:100%;最大宽度:100%;}#list.nowrap{空白:nowrap;}#secondlist{溢出:自动;最大宽度:250px;空白:nowrap;}.项目清单{显示:内联块;宽度:50px;高度:50px;边距:2px;背景:紫色;}.list-item.odd{背景:紫罗兰;}#帮助窗格{显示:无;弹性:0 0 0px;背景:红色;}#help-pane.visible{显示:继承;弹性: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="左"><div id="导航">- 菜单 -
<div id="help-toggle">帮助切换
<div id="导航切换">导航切换
<div id="list-toggle">列表空白切换
<div id="mid"><div id="中顶">- 中上 -
<div id="中底">- 中底- <br><br><div id="列表"><div class="list-itemodd"> </div><div class="list-item"> </div><div class="list-itemodd"> </div><div class="list-item"> </div><div class="list-itemodd"> </div><div class="list-item"> </div><div class="list-itemodd"> </div><div class="list-item"> </div><div class="list-itemodd"> </div><div class="list-item"> </div><div class="list-itemodd"> </div>
<小时><div id="secondlist"><div class="list-itemodd"> </div><div class="list-item"> </div><div class="list-itemodd"> </div><div class="list-item"> </div><div class="list-itemodd"> </div><div class="list-item"> </div><div class="list-itemodd"> </div><div class="list-item"> </div><div class="list-itemodd"> </div><div class="list-item"> </div><div class="list-itemodd"> </div>
<div id="help-pane" class="visible">- 帮助面板 -
解决方案
这是由 默认的 flex-box 行为,防止 flex-box 变得比它的内容小.
此问题的解决方案是将 min-width: 0
(或 min-height: 0 用于列)设置为所有父弹性框.在这种特定情况下(以及在 fiddle 中):
#shell{弹性:1 1 自动;显示:弹性;flex-flow:row nowrap;位置:相对;宽度:100%;最小高度:100%;最小宽度:0;/* 这个就在这里做!*/}
<小时>
$('#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;}#身体{显示:弹性;flex-flow:row nowrap;位置:绝对;顶部:0;左:0;保证金:0;填充:0;宽度:100%;高度:100%;背景色:#abc;溢出:隐藏;}#壳{弹性:1 1 自动;显示:弹性;flex-flow:row nowrap;位置:相对;宽度:100%;最小高度:100%;最小宽度:0;}#剩下{弹性:0 0 180px;最小高度:100%;最小宽度:0;背景:浅蓝色;}#left.collapsed{弹性:0 0 80px;}#中{弹性:1 1 自动;最小高度:100%;最小宽度:0;显示:弹性;flex-flow:column nowrap;对齐项目:拉伸;对齐内容:拉伸;位置:相对;宽度:100%;最小高度:100vh;最小宽度:0;背景:紫色;}#中上{弹性:0 0 自动;最小高度:100px;背景:绿色;}#中底{最小高度:计算(100% - 100px);弹性:1 1 自动;背景:浅绿色;}#列表{溢出:自动;宽度:100%;最大宽度:100%;}#list.nowrap{空白:nowrap;}#secondlist{溢出:自动;最大宽度:250px;空白:nowrap;}.项目清单{显示:内联块;宽度:50px;高度:50px;边距:2px;背景:紫色;}.list-item.odd{背景:紫罗兰;}#帮助窗格{显示:无;弹性:0 0 0px;背景:红色;}#help-pane.visible{显示:继承;弹性: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="左"><div id="导航">- 菜单 -
<div id="help-toggle">帮助切换
<div id="导航切换">导航切换
<div id="list-toggle">列表空白切换
<div id="mid"><div id="中顶">- 中上 -
<div id="中底">- 中底- <br><br><div id="列表"><div class="list-itemodd"> </div><div class="list-item"> </div><div class="list-itemodd"> </div><div class="list-item"> </div><div class="list-itemodd"> </div><div class="list-item"> </div><div class="list-itemodd"> </div><div class="list-item"> </div><div class="list-itemodd"> </div><div class="list-item"> </div><div class="list-itemodd"> </div>
<小时><div id="secondlist"><div class="list-itemodd"> </div><div class="list-item"> </div><div class="list-itemodd"> </div><div class="list-item"> </div><div class="list-itemodd"> </div><div class="list-item"> </div><div class="list-itemodd"> </div><div class="list-item"> </div><div class="list-itemodd"> </div><div class="list-item"> </div><div class="list-itemodd"> </div>
<div id="help-pane" class="visible">- 帮助面板 -
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).
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.
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
.
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/
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.
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.
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屋!
查看全文