Flexbox带有可滚动面板

时间:2016-05-04 15:39:06

标签: html css css3 flexbox

我正在尝试实现一种拉伸以填充屏幕的布局,但是当内容大于可用窗格时滚动。

我有一个基于this answer的基本flexbox方法,它可以很好地填满屏幕,但内容溢出会导致整个屏幕滚动而不仅仅是自己的容器。

如果我将.outer高度更改为200px这样的文字值,那么我会得到我想要的滚动行为,但是底部内容窗格不再填满屏幕。

我尝试使用display: table和相关的CSS而不是flexbox,但结果却相同。

我还考虑在内容窗格的高度上使用calc - 类似于

height: calc(100% - 60px);

但是我希望标题能够随着内容的增长而增长,所以我的计算高度并不高。

我正在寻找一个纯CSS解决方案,而不是使用某种风格的Javascript进行窗口大小调整。



html,
body {
  height: 100%;
  margin: 0
}
.box {
  display: flex;
  flex-flow: column;
  height: 100%;
}
.box .row {
  border: 1px dotted grey;
  flex: 1 1 auto;
}
.box .row.header {
  background: aliceblue;
}
.box .row.content {
  background: pink;
}
.box .row.content .title {
  height: 40px;
  background: yellow;
}
.outer {
  height: -webkit-calc(100% - 40px);
  height: -moz-calc(100% - 40px);
  height: -o-calc(100% - 40px);
  height: calc(100% - 40px);
  overflow-y: auto;
}
.inner {
  height: 100%;
}
.text {
  height: 100px;
  margin-top: 10px;
  border: 1px solid gold;
}

<div class="box">
  <div class="row header">
    <p><b>header</b>
      <br />
      <br />(sized to content)</p>
  </div>
  <div class="row content">
    <div class="title">
      <b>content</b>
      (fills remaining space)
    </div>
    <div class="outer">
      <div class="inner">
        <div class="text">Bacon ipsum dolor amet tongue corned beef landjaeger sausage beef meatball, kielbasa pastrami turkey boudin hamburger ham hock chuck tail pork. Shankle tail cupim ribeye.</div>
        <div class="text">Bacon ipsum dolor amet tongue corned beef landjaeger sausage beef meatball, kielbasa pastrami turkey boudin hamburger ham hock chuck tail pork. Shankle tail cupim ribeye.</div>
        <div class="text">Bacon ipsum dolor amet tongue corned beef landjaeger sausage beef meatball, kielbasa pastrami turkey boudin hamburger ham hock chuck tail pork. Shankle tail cupim ribeye.</div>
        <div class="text">Bacon ipsum dolor amet tongue corned beef landjaeger sausage beef meatball, kielbasa pastrami turkey boudin hamburger ham hock chuck tail pork. Shankle tail cupim ribeye.</div>
        <div class="text">Bacon ipsum dolor amet tongue corned beef landjaeger sausage beef meatball, kielbasa pastrami turkey boudin hamburger ham hock chuck tail pork. Shankle tail cupim ribeye.</div>
        <div class="text">Bacon ipsum dolor amet tongue corned beef landjaeger sausage beef meatball, kielbasa pastrami turkey boudin hamburger ham hock chuck tail pork. Shankle tail cupim ribeye.</div>
        <div class="text">Bacon ipsum dolor amet tongue corned beef landjaeger sausage beef meatball, kielbasa pastrami turkey boudin hamburger ham hock chuck tail pork. Shankle tail cupim ribeye.</div>
      </div><!-- inner -->
    </div><!-- outer -->
  </div>
</div>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:3)

希望这是你期望的行为。

html,
body {
  height: 100%;
  widht: 100%;
}

body {
  margin: 0;
  padding: 0;
}

.box {
  display: flex;
  flex-flow: column;
  flex-wrap: nowrap;
  height: 100%;
}
.box .row {
  border: 1px dotted grey;
  flex: 0 0 auto;
  overflow: auto;
}
.box .row.header {
  background: aliceblue;
}
.box .row.content {
  flex: 1 1 auto;
  display: flex;
  flex-flow: column;
  flex-wrap: nowrap;
  background: pink;
}
.box .row.content .title {
  height: 40px;
  background: yellow;
  flex: 0 0 auto;
}
.text {
  height: 100px;
  margin-top: 10px;
  border: 1px solid gold;
}
.outer {
  height: 100%;
  flex: 1 1 auto;
  overflow-y: auto;
}
.inner {
  height: 100%;
}
<div class="box">
  <div class="row header">
    <p><b>header</b>
      <br />
      <br />(sized to content)</p>
  </div>
  <div class="row content">
    <div class="title">
      <b>content</b>
      (fills remaining space)
    </div>

    <div class="outer">

      <div class="inner">
        <div class="text">Bacon ipsum dolor amet tongue corned beef landjaeger sausage beef meatball, kielbasa pastrami turkey boudin hamburger ham hock chuck tail pork. Shankle tail cupim ribeye.</div>
        <div class="text">Bacon ipsum dolor amet tongue corned beef landjaeger sausage beef meatball, kielbasa pastrami turkey boudin hamburger ham hock chuck tail pork. Shankle tail cupim ribeye.</div>
        <div class="text">Bacon ipsum dolor amet tongue corned beef landjaeger sausage beef meatball, kielbasa pastrami turkey boudin hamburger ham hock chuck tail pork. Shankle tail cupim ribeye.</div>
        <div class="text">Bacon ipsum dolor amet tongue corned beef landjaeger sausage beef meatball, kielbasa pastrami turkey boudin hamburger ham hock chuck tail pork. Shankle tail cupim ribeye.</div>
        <div class="text">Bacon ipsum dolor amet tongue corned beef landjaeger sausage beef meatball, kielbasa pastrami turkey boudin hamburger ham hock chuck tail pork. Shankle tail cupim ribeye.</div>
        <div class="text">Bacon ipsum dolor amet tongue corned beef landjaeger sausage beef meatball, kielbasa pastrami turkey boudin hamburger ham hock chuck tail pork. Shankle tail cupim ribeye.</div>
        <div class="text">Bacon ipsum dolor amet tongue corned beef landjaeger sausage beef meatball, kielbasa pastrami turkey boudin hamburger ham hock chuck tail pork. Shankle tail cupim ribeye.</div>

      </div>
      <!-- inner -->

    </div>
    <!-- outer -->


  </div>
</div>

答案 1 :(得分:1)

此布局的关键是识别弹性项目的最小尺寸

  

4.5. Implied Minimum Size of Flex Items

     

为flex项提供更合理的默认最小大小,这个   规范引入了一个新的auto值作为初始值   CSS 2.1中定义的min-widthmin-height属性。

换句话说,默认情况下,弹性项目永远不会小于其内容的大小。

弹性项目的初始设置:

min-width: auto;
min-height: auto;

这有可能强制物品溢出其容器。

解决方案是在Flex容器上应用min-width: 0进行水平滚动,将min-height: 0用于垂直滚动。

下面是使用您的代码的简化演示(JS只是重复.text元素):

function multiplyNode(node, count, deep) {
    for (var i = 0, copy; i < count - 1; i++) {
        copy = node.cloneNode(deep);
        node.parentNode.insertBefore(copy, node);
    }
}

multiplyNode(document.querySelector('.text'), 10, true);
* { box-sizing: border-box; }

html, body {
  height: 100%;
  margin: 0;
  border: 1px solid black;
}

.box {
  display: flex;
  flex-flow: column;
  height: 100%;
}

.header {
    background-color: aqua;
    flex: 0 0 auto;
}

.content {
    background-color: yellow;
    flex: 1;
    display: flex;              /* new */
    flex-direction: column;     /* new */   
    min-height: 0;              /* new; allow flex item to be smaller than its content,
                                   enabling scroll */
}

.outer {
    background-color: pink;
    flex: 1;
    overflow-y: auto;
}

.text {
  height: 100px;
  margin-top: 10px;
  border: 1px solid gold;
}
<div class="box">
     <div class="header">header (sized to content, i.e., height: auto;)</div>
     <div class="content">content (fills remaining space, i.e. flex: 1;)
          <div class="outer">
              <div class="inner">
                   <div class="text">Bacon ipsum dolor amet tongue corned beef landjaeger sausage beef meatball, kielbasa pastrami turkey boudin hamburger ham hock chuck tail pork. Shankle tail cupim ribeye.</div>
                   </div><!-- inner -->
          </div><!-- outer -->
     </div><!-- content -->
</div><!-- box -->

在Chrome,FF和IE11上测试过。

更多信息: