将flexbox嵌套在flexbox溢出内。如何解决这个问题?

时间:2018-01-22 20:47:55

标签: html css css3 flexbox scrollbar

所以我试图通过将#mainheight: 100%作为flexbox来获取标题和一些内容以适应屏幕,就像这样:

#main {
    height: 150px; /* Using a fixed height here, otherwise the snippet wouldn't work */
}
.flexbox {
    display: flex;
    flex-direction: column;
}
.header {
    flex: 0 1 auto;
    border: 2px solid #aa0000;
}
.content {
    flex: 1 1 auto;
    border: 2px solid #00aa00;
}
.scrollable {
    overflow-y: scroll;
}
<html>
    <body>
        <div id="main" class="flexbox">
            <div class="header">
                HEADER
            </div>
            <div class="content scrollable">
                CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
                CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
                CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
                CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
            </div>
        </div>
    </body>
</html>

现在,如果#content溢出#main的高度,#content的滚动条将会接管,标题仍然可见。到目前为止,它就像一个魅力。

我现在的问题是我需要将标题和屏幕拟合内容的另一个组合嵌套到外部内容中,我试图用另一个嵌套的flexbox解决这个问题:

#main {
    height: 150px; /* Using a fixed height here, otherwise the snippet wouldn't work */
}
.flexbox {
    display: flex;
    flex-direction: column;
}
.header {
    flex: 0 1 auto;
    border: 2px solid #aa0000;
}
.content {
    flex: 1 1 auto;
    border: 2px solid #00aa00;
}
.scrollable {
    overflow-y: scroll;
}
<html>
    <body>
        <div id="main" class="flexbox">
            <div class="header">
                HEADER
            </div>
            <div class="content flexbox">
                <div class="header">
                    HEADER
                </div>
                <div class="content scrollable">
                    CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
                    CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
                    CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
                    CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
                </div>
            </div>
        </div>
    </body>
</html>

所以基本上我希望两个标题现在保持最高位置,并且只有内部内容框一旦溢出就滚动。但是当它发生时,内容会超出(?!)#main的高度,触发浏览器页面的滚动条而不是它自己的滚动条。我想问题可能是由外部内容框引起的,外部框的高度仅由外部flexbox定义。

我已经尝试了一个解决方案,其中标题将具有绝对位置,但这并不能解决我需要它的问题。如果不是这个问题,Flexboxes将是完美的。

任何人都可以帮我解决这个问题吗?

3 个答案:

答案 0 :(得分:1)

您要求的内容已经在Chrome中发生了。这让我觉得你正在用FF开发。

作为旁注,我认为这是一个错误,仅仅是因为您只为不到15%的目标受众进行了开发,只为另外65%的受众修复了浏览器差异。幸运的是,他们都严格遵守标准,而且这些日子的差异很小 您可能更喜欢使用Chrome over FF作为开发工具的另一个原因是,FF至少4年来一直落后于开发工具6个月。不要误会我的意思,我不是Chrome的忠实粉丝,我完全欢迎使用FF作为首选的浏览设备。但是,作为一种开发工具,它并不是最好的。他们都是自由的。

回到你的问题,将overflow-y:auto添加到.flexbox似乎也可以在FF修复它:

#main {
    height: 150px; /* Using a fixed height here, otherwise the snippet wouldn't work */
}
.flexbox {
    display: flex;
    flex-direction: column;
    overflow-y: auto;
}
.header {
    flex: 0 1 auto;
    border: 2px solid #aa0000;
}
.content {
    flex: 1 1 auto;
    border: 2px solid #00aa00;
}
.scrollable {
    overflow-y: scroll;
}
<html>
    <body>
        <div id="main" class="flexbox">
            <div class="header">
                HEADER
            </div>
            <div class="content flexbox">
                <div class="header">
                    HEADER
                </div>
                <div class="content scrollable">
                    CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
                    CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
                    CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
                    CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br>
                </div>
            </div>
        </div>
    </body>
</html>

注意:当然,您需要通过prefixer运行代码以获得更广泛的浏览器覆盖率。注意它下面的“过滤器”框。设置为> 0%以获得最大的跨浏览器兼容性。

答案 1 :(得分:1)

此问题不仅影响Firefox,还影响Edge和IE11溢出父级。

这是因为flex项目的min-height *默认为auto,因此不能小于其内容。 (Chrome会尝试自行修复此问题,因此可以使用它,但是,恕我直言,它不应该这样做)

*这里解释得非常好:The Implied Minimum Size of Flex Items

受影响的元素是<div class="content flexbox">,如果发生这种情况会溢出。

解决方案是将其min-height更改为0,这样就可以缩小过去的内容。

对于IE11,请参阅下面的注释/示例。

Stack snippet

#main {
    height: 150px; /* Using a fixed height here, otherwise the snippet wouldn't work */
}
.flexbox {
    display: flex;
    flex-direction: column;
}
.header {
    /*flex: 0 1 auto;                       default, so not needed  */
    border: 2px solid #aa0000;
}
.content {
    flex: 1 1 auto;
    border: 2px solid #00aa00;
    min-height: 0;                      /*  Firefox, Edge  */
}
.scrollable {
    overflow-y: scroll;
}
<div id="main" class="flexbox">
  <div class="header">
    HEADER
  </div>
  <div class="content flexbox">
    <div class="header">
      HEADER
    </div>
    <div class="content scrollable">
      CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br> CONTENT
      <br>CONTENT<br>CONTENT<br>CONTENT<br> CONTENT
      <br>CONTENT<br>CONTENT<br>CONTENT<br> CONTENT
      <br>CONTENT<br>CONTENT<br>CONTENT<br>
    </div>
  </div>
</div>

由于IE11很麻烦,以上是不够的,有两种方法可以解决它:

使用flex: 1 1 0%,这将使IE11相信没有内容,因此只会增加其父级的可用空间。

#main {
    height: 150px; /* Using a fixed height here, otherwise the snippet wouldn't work */
}
.flexbox {
    display: flex;
    flex-direction: column;
}
.header {
    /*flex: 0 1 auto;                       default, so not needed  */
    border: 2px solid #aa0000;
}
.content {
    flex: 1 1 0%;                       /*  IE11, changed from "auto" to "0%" */
    border: 2px solid #00aa00;
    min-height: 0;                      /*  Firefox, Edge  */
}
.scrollable {
    overflow-y: scroll;
}
<div id="main" class="flexbox">
  <div class="header">
    HEADER
  </div>
  <div class="content flexbox">
    <div class="header">
      HEADER
    </div>
    <div class="content scrollable">
      CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br> CONTENT
      <br>CONTENT<br>CONTENT<br>CONTENT<br> CONTENT
      <br>CONTENT<br>CONTENT<br>CONTENT<br> CONTENT
      <br>CONTENT<br>CONTENT<br>CONTENT<br>
    </div>
  </div>
</div>

使用overflow: hidden(请参阅末尾的说明)

#main {
    height: 150px; /* Using a fixed height here, otherwise the snippet wouldn't work */
}
.flexbox {
    display: flex;
    flex-direction: column;
}
.header {
    /*flex: 0 1 auto;                       default, so not needed  */
    border: 2px solid #aa0000;
}
.content {
    flex: 1 1 auto;
    border: 2px solid #00aa00;
    /*min-height: 0;                        not needed, as overflow has same effect  */
    overflow: hidden;                   /*  Firefox, Edge, IE11  */
}
.scrollable {
    overflow-y: scroll;
}
<div id="main" class="flexbox">
  <div class="header">
    HEADER
  </div>
  <div class="content flexbox">
    <div class="header">
      HEADER
    </div>
    <div class="content scrollable">
      CONTENT<br>CONTENT<br>CONTENT<br>CONTENT<br> CONTENT
      <br>CONTENT<br>CONTENT<br>CONTENT<br> CONTENT
      <br>CONTENT<br>CONTENT<br>CONTENT<br> CONTENT
      <br>CONTENT<br>CONTENT<br>CONTENT<br>
    </div>
  </div>
</div>

请注意,使用值overflow以外的visible(默认值),效果与min-height相同,其中hidden被视为更多安全于auto,避免将来改变行为以呈现滚动条。

答案 2 :(得分:0)

您可以通过在主框和内容框上使用两个height: 0来解决此问题。

html,
body {
  height: 100%;
}

.topheader {
  background: orange;
  width: 90%;
}

#container {
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 50%;
  background: red;
}


.subcontainer {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  height: 0;
  width: 90%;
  background: blue;
}

#container header {
  background-color: gray;
}

#container article {
  flex: 1 1 auto;
  overflow-y: auto;
  height: 0;
  opacity: 0.5;

}

#container footer {
  background-color: gray;
}
<section id="container">
  <div class="topheader">
    Top Header
  </div>
  <div class="subcontainer">
    <header id="header">This is a header</header>
    <article id="content">
      This is the content that
      <br />
      With a lot of lines.
      <br />
      With a lot of lines.
      <br />
      This is the content that
      <br />
      With a lot of lines.
      <br />
      <br />
      This is the content that
      <br />
      With a lot of lines.<br />
      With a lot of lines.
      <br />
      This is the content that
      <br />
      With a lot of lines.
      <br />
      <br />
      This is the content that
      <br />
      With a lot of lines<br />
      With a lot of lines.
      <br />
      This is the content that
      <br />
      With a lot of lines.
      <br />
      <br />
      This is the content that
      <br />
      With a lot of lines
      <br />
      <br />
      This is the content that
      <br />
      With a lot of lines.
      <br />
    </article>
    <footer id="footer">This is a footer</footer>
  </div>
</section>