空白:nowrap 打破了 flexbox 布局 [英] white-space: nowrap breaks flexbox layout

查看:32
本文介绍了空白:nowrap 打破了 flexbox 布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 Flexbox 为应用程序创建了响应式布局.布局要求左侧有一个可折叠的菜单,中间有一个标题和正文的块,右侧有一个可切换的帮助窗格(还有更多内容,但这是基本结构).

左侧菜单有两种状态:180 像素宽或 80 像素宽.帮助窗格要么隐藏,要么占用 180 像素.中间的盒子占据了其余的空间.Flexbox 就像一个魅力.

当我使用 white-space: nowrap 制作滚动 div 时,麻烦就开始了.我有一堆需要在水平滚动条中显示的项目,所以我有一个包含项目的列表 div,设置为 overflow:autowhite-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">&nbsp;</div><div class="list-item">&nbsp;</div><div class="list-itemodd">&nbsp;</div><div class="list-item">&nbsp;</div><div class="list-itemodd">&nbsp;</div><div class="list-item">&nbsp;</div><div class="list-itemodd">&nbsp;</div><div class="list-item">&nbsp;</div><div class="list-itemodd">&nbsp;</div><div class="list-item">&nbsp;</div><div class="list-itemodd">&nbsp;</div>

<小时><div id="secondlist"><div class="list-itemodd">&nbsp;</div><div class="list-item">&nbsp;</div><div class="list-itemodd">&nbsp;</div><div class="list-item">&nbsp;</div><div class="list-itemodd">&nbsp;</div><div class="list-item">&nbsp;</div><div class="list-itemodd">&nbsp;</div><div class="list-item">&nbsp;</div><div class="list-itemodd">&nbsp;</div><div class="list-item">&nbsp;</div><div class="list-itemodd">&nbsp;</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">&nbsp;</div><div class="list-item">&nbsp;</div><div class="list-itemodd">&nbsp;</div><div class="list-item">&nbsp;</div><div class="list-itemodd">&nbsp;</div><div class="list-item">&nbsp;</div><div class="list-itemodd">&nbsp;</div><div class="list-item">&nbsp;</div><div class="list-itemodd">&nbsp;</div><div class="list-item">&nbsp;</div><div class="list-itemodd">&nbsp;</div>

<小时><div id="secondlist"><div class="list-itemodd">&nbsp;</div><div class="list-item">&nbsp;</div><div class="list-itemodd">&nbsp;</div><div class="list-item">&nbsp;</div><div class="list-itemodd">&nbsp;</div><div class="list-item">&nbsp;</div><div class="list-itemodd">&nbsp;</div><div class="list-item">&nbsp;</div><div class="list-itemodd">&nbsp;</div><div class="list-item">&nbsp;</div><div class="list-itemodd">&nbsp;</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">&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>

解决方案

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">&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>

这篇关于空白:nowrap 打破了 flexbox 布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆