滚动带有溢出内容的Flexbox

Jos*_*ber 183 css layout css3 multiple-columns flexbox

在此输入图像描述

这是我用来实现上述布局的代码:

.header {
  height: 50px;
}

.body {
  position: absolute;
  top: 50px;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
}

.sidebar {
  width: 140px;
}

.main {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.content {
  flex: 1;
  display: flex;
}

.column {
  padding: 20px;
  border-right: 1px solid #999;
}
Run Code Online (Sandbox Code Playgroud)
<div class="header">Main header</div>
<div class="body">
  <div class="sidebar">Sidebar</div>

  <div class="main">
    <div class="page-header">Page Header. Content columns are below.</div>
    <div class="content">
      <div class="column">Column 1</div>
      <div class="column">Column 1</div>
      <div class="column">Column 1</div>
    </div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

我省略了用于样式的代码.你可以在笔中看到所有这些.


上面的工作,但当该content区域的内容溢出时,它会使整个页面滚动.我只希望内容区域本身滚动,所以我添加overflow: autocontentdiv.

现在的问题是列本身不会超出其父级高度,因此边界也被切断.

这是显示滚动问题的笔.

如何将content区域设置为独立滚动,同时让其子项超出content框的高度?

Jos*_*ber 233

我已经和Tab Atkins(flexbox规范的作者)谈过这个问题,这就是我们想出来的:

HTML:

<div class="content">
    <div class="box">
        <div class="column">Column 1</div>
        <div class="column">Column 1</div>
        <div class="column">Column 1</div>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

CSS:

.content {
    flex: 1;
    display: flex;
    overflow: auto;
}

.box {
    min-height: min-content; /* needs vendor prefixes */
    display: flex;
}
Run Code Online (Sandbox Code Playgroud)

这是钢笔:

  1. 短柱被拉伸.
  2. 更长的列溢出和滚动.

这样做的原因是因为align-items: stretch如果它们具有固有高度,则不会缩小其项目,这在此处完成min-content.

  • 是的,这在IE11中被破坏了 (4认同)
  • 它们在父母的身高不依赖于孩子的情况下工作,一般来说就是这种情况.min-height:100%确实可以修复Firefox中的弹力 - 甚至是列时短的问题(尽管不在Chrome中).不确定是否是Chrome错误或Firefox错误. (3认同)
  • 请注意,Firefox目前仅支持宽度值的"min-content",而不支持高度值 - 因此,如果对您而言,这在Firefox中不起作用.(参见https://bugzilla.mozilla.org/show_bug.cgi?id=852367) (2认同)
  • @dholbert - 这些笔的问题在于它们是公开的,所以任何人都可以改变它们.我取得了他们的所有权,所以在这里你去:http://codepen.io/JosephSilber/pen/pmyHh (2认同)

geo*_*eon 82

经过大量的试验和错误后,我才非常优雅地解决了这个问题.

看看我的博客文章:http://geon.github.io/programming/2016/02/24/flexbox-full-page-web-app-layout

基本上,要使flexbox单元格可滚动,您必须创建其所有父项 overflow: hidden;,否则它将忽略您的溢出设置并使父项更大.

  • 这也适用于我的情况,但哇,我真的很想看到*为什么*它有效的解释.大多数时候,我发现CSS规范对于这种事情是完全不可理解的. (7认同)
  • 我在[这里](https://medium.com/@stephenbunch/how-to-make-a-scrollable-container-with-dynamic-height-using-flexbox-5914a26ae336)找到了技术原因,然后[正式在这里( CSS 规范)](https://drafts.c​​sswg.org/css-flexbox-1/#min-size-auto)。基本上,更改溢出会更改最小高度自动值。尝试将“溢出隐藏”替换为“溢出自动”或“最小高度0”。一切都应该仍然有效,并且后者应该是首选(或者至少我在阅读规范后明白这一点)。 (5认同)
  • 我不确定是否能真正解释它.将overflow设置为隐藏在元素上不会阻止它扩展以包含其所有子元素AFAIK.根据MDN:"overflow属性指定是否剪辑内容,渲染滚动条或仅在溢出其块级容器时显示内容." 此外,将溢出设置为除可见之外的任何内容都会创建一个新的块格式化上下文 - 但这不相关,因为Flex容器已经创建了自己的块格式化上下文:https://developer.mozilla.org/en-US/docs /网络/指南/ CSS/Block_formatting_context. (3认同)
  • 从您的博客文章中:_“我不知道为什么会这样,而且规范也没有说明”。因此,我正在寻找它为什么起作用的解释。我已经浏览了这些规格,但是正如您所说的,没有什么可以跳过的。 (2认同)
  • 再考虑一下之后,我认为这是有道理的。默认行为是使每个div扩展以包含其所有子级,因此不会在叶节点处隐藏任何溢出。您需要强制溢出:从DOM的顶部一直隐藏,所以直到您下到要溢出和滚动的节点为止,父级都没有机会容纳它的孩子。 (2认同)
  • 我应该补充一点,我同意你的解释具有*直观*意义,但我认为这不是一个准确的*技术*解释,这正是我想要的。只有真正了解原因,我才能记住未来的解决方案! (2认同)

Aka*_*ash 38

与... position:absolute;一起工作flex:

定位弹性项目position: relative.然后在其中添加另一个<div>元素:

position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
Run Code Online (Sandbox Code Playgroud)

这会将元素扩展到其相对定位父级的边界,但不允许扩展它.在里面,overflow: auto;然后将按预期工作.

  • 答案中包含的代码段 - 单击 在此输入图像描述 然后单击 完整页面运行代码片段后OR
  • 点击这里查看CODEPEN
  • 结果: 在此输入图像描述

.all-0 {
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
p {
  text-align: justify;
}
.bottom-0 {
  bottom: 0;
}
.overflow-auto {
  overflow: auto;
}
Run Code Online (Sandbox Code Playgroud)
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" rel="stylesheet"/>


<div class="p-5 w-100">
  <div class="row bg-dark m-0">
    <div class="col-sm-9 p-0 d-flex flex-wrap">
      <!-- LEFT-SIDE - ROW-1 -->
      <div class="row m-0 p-0">
        <!-- CARD 1 -->
        <div class="col-md-8 p-0 d-flex">
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">
            <img class="img img-fluid" src="https://via.placeholder.com/700x250">
            <h4>Heading 1</h4>
            <p>
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old...
          </div>
        </div>
        <!-- CARD 2 -->
        <div class="col-md-4 p-0 d-flex">
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">
            <img class="img img-fluid" src="https://via.placeholder.com/400x250">
            <h4>Heading 1</h4>
            <p>
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old...
          </div>
        </div>
      </div>
      <div class="row m-0">
        <!-- CARD 3 -->
        <div class="col-md-4 p-0 d-flex">
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">
            <img class="img img-fluid" src="https://via.placeholder.com/400x250">
            <h4>Heading 1</h4>
            <p>
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old...
          </div>
        </div>
        <!-- CARD 4 -->
        <div class="col-md-4 p-0 d-flex">
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">
            <img class="img img-fluid" src="https://via.placeholder.com/400x250">
            <h4>Heading 1</h4>
            <p>
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old...
          </div>
        </div>
        <!-- CARD 5-->
        <div class="col-md-4 p-0 d-flex">
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">
            <img class="img img-fluid" src="https://via.placeholder.com/400x250">
            <h4>Heading 1</h4>
            <p>
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old...
          </div>
        </div>
      </div>
    </div>
    <div class="col-sm-3 p-0">
      <div class="bg-white m-2 p-2 position-absolute all-0 d-flex flex-column">
        <h4>Social Sidebar...</h4>
        <hr />
        <div class="d-flex overflow-auto">
          <p>
            Topping candy tiramisu soufflé fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halva fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart.
            opping candy tiramisu soufflé fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halva fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart.
            opping candy tiramisu soufflé fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halva fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart.
            Pudding cupcake danish apple pie apple pie. Halvafruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halvafruitcake ice cream chocolate bar. Bear claw ice cream
            chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halvafruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halvafruitcake ice cream chocolate
            bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halva
        </div>
      </div>
    </div>
  </div>
Run Code Online (Sandbox Code Playgroud)

祝好运...

  • 如果内部组件设置了填充,则此解决方案特别有用,因为它可以将其很好地锁定在所需的位置。这要简单得多。(是的,您可以设置`box-sizing:border-box`,但是对于某些第三方控件来说可能更复杂)。 (2认同)
  • 你救了我一晚! (2认同)
  • 谢谢。不知怎的,我对这是必要的感到失望,但我很感激你的建议! (2认同)
  • 这比两个最重要的答案简单得多...我希望在开始尝试之前我已经阅读了所有答案:) 完美地工作 (2认同)

Sep*_*eed 17

我在任何地方都没有看到这个答案。但我需要的技巧是确保这些物品有一个flex-shrink: 0; 否则他们会被挤压。

.container {
  display: flex;
  overflow: auto
}

.container > * {
  flex-shrink: 0;
  width: 10em;
  height: 10em;
  background: linear-gradient(to bottom right, #F0F, #0FF);
}
Run Code Online (Sandbox Code Playgroud)
<div class="container">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>
Run Code Online (Sandbox Code Playgroud)


Chr*_*cki 15

以下粗体 CSS 更改(加上列中的一堆内容以测试滚动)将起作用。好吧,它使每个内容列都可以单独滚动,这可能比最初要求的更多(更好?)。无论如何,看看这支笔的结果。

.content { 弹性:1; 显示:柔性; 高度:1px;}

.column { 填充:20px; 右边框:1px 实线#999;溢出:自动;}

这里的技巧似乎是,可滚动面板需要height在某个地方进行字面设置(在本例中,通过其父级),而不仅仅是由 Flexbox 确定。所以甚至height: 1px有效。仍将flex-grow:1调整面板尺寸以使其正确安装。


Dou*_*eri 8

有点晚了但这可能会有所帮助:http: //webdesign.tutsplus.com/tutorials/how-to-make-responspons-scrollable-panels-with-flexbox--cms-23269

基本上,你需要把html,bodyheight: 100%; 和包装所有内容成<div class="wrap"> <!-- content --> </div>

CSS:

html, body {
  height: 100%;
}

.wrap {
  height: 100vh;
  display: flex;
}
Run Code Online (Sandbox Code Playgroud)

为我工作.希望能帮助到你

  • 使用“height: 100vh”时应非常小心,因为它在 iOS Safari 与 Android 中的测量方式不同。一种考虑了 URL 栏的高度,另一种则不考虑。 (3认同)

dho*_*ert 6

添加:

align-items: flex-start;
Run Code Online (Sandbox Code Playgroud)

遵守规则.content {}。至少(无论是Firefox还是Chrome),这都能为您解决。

默认情况下,.contenthas align-items: stretch可以根据http://dev.w3.org/csswg/css-flexbox/#algo-stretch调整其所有自动高度子项的大小以匹配其自身的高度。相反,该值flex-start可让子代计算自己的高度,并使其在其起始边缘对齐(并溢出,并触发滚动条)。


Lia*_*iam 5

我遇到的一个问题是,要拥有滚动条,元素需要指定高度(而不是百分比)。

诀窍是在每列中嵌套另一组 div,并使用 flex-direction: column 将列父级的显示设置为 Flex。

<style>
    html, body {
        height: 100%;
        margin: 0;
        padding: 0;
    }

    body {
        overflow-y: hidden;
        overflow-x: hidden;
        color: white;
    }

    .base-container {
        display: flex;
        flex: 1;
        flex-direction: column;
        width: 100%;
        height: 100%;
        overflow-y: hidden;
        align-items: stretch;
    }

    .title {
        flex: 0 0 50px;
        color: black;
    }

    .container {
        flex: 1 1 auto;
        display: flex;
        flex-direction: column;
    }

        .container .header {
            flex: 0 0 50px;
            background-color: red;
        }

        .container .body {
            flex: 1 1 auto;
            display: flex;
            flex-direction: row;
        }

            .container .body .left {
                display: flex;
                flex-direction: column;
                flex: 0 0 80px;
                background-color: blue;
            }
                .container .body .left .content,
                .container .body .main .content,
                .container .body .right .content {
                    flex: 1 1 auto;
                    overflow-y: auto;
                    height: 100px;
                }
                .container .body .main .content.noscrollbar {
                    overflow-y: hidden;
                }

            .container .body .main {
                display: flex;
                flex-direction: column;
                flex: 1 1 auto;
                background-color: green;
            }

            .container .body .right {
                display: flex;
                flex-direction: column;
                flex: 0 0 300px;
                background-color: yellow;
                color: black;
            }

    .test {
        margin: 5px 5px;
        border: 1px solid white;
        height: calc(100% - 10px);
    }
</style>
Run Code Online (Sandbox Code Playgroud)

这是 HTML:

<div class="base-container">
    <div class="title">
        Title
    </div>
    <div class="container">
        <div class="header">
            Header
        </div>
        <div class="body">
            <div class="left">
                <div class="content">
                    <ul>
                        <li>1</li>
                        <li>2</li>
                        <li>3</li>
                        <li>4</li>
                        <li>5</li>
                        <li>6</li>
                        <li>7</li>
                        <li>8</li>
                        <li>9</li>
                        <li>10</li>
                        <li>12</li>
                        <li>13</li>
                        <li>14</li>
                        <li>15</li>
                        <li>16</li>
                        <li>17</li>
                        <li>18</li>
                        <li>19</li>
                        <li>20</li>
                        <li>21</li>
                        <li>22</li>
                        <li>23</li>
                        <li>24</li>
                    </ul>
                </div>
            </div>
            <div class="main">
                <div class="content noscrollbar">
                    <div class="test">Test</div>
                </div>
            </div>
            <div class="right">
                <div class="content">
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>End</div>
                </div>
            </div>
        </div>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

https://jsfiddle.net/LiamFlavelle/czpjdfr4/


小智 5

这个问题的解决方案就是添加overflow: auto;到 .content 以使内容包装器可滚动。

此外,还有一些情况与 Flexbox 包装器和overflowed可滚动内容一起发生,例如codepen

解决方案是overflow: hidden (or auto);在大内容周围添加到包装器的父级(使用 Overflow: auto; 设置)。