子级div高度超过了Firefox中的父级高度而不是Chrome

Gar*_*ary 4 css firefox flexbox twitter-bootstrap

如何防止使用滚动条的子div和flex:1超出其在Firefox中的父Flexbox的高度?它在Chrome中正常运行.

CodePen链接(如果您更喜欢Stack Overflow片段):https://codepen.io/garyapps/pen/ZMNVJg

细节:

我有一个固定高度的弹性容器.它有一个flex-direction:column设置,它包含多个垂直堆叠的孩子div.其中一个儿童div被赋予flex:1财产,而其他人则获得固定的高度.

我的期望是带有flex:1财产的子女孩将扩大以填补剩余的垂直空间.这按预期工作.

我还给了孩子div一个overflow-y:scroll属性,所以如果它内的内容超过它的高度,就会出现滚动条.这在Chrome中运行良好.然而,在Firefox中,这个孩子的身高会增加,超过其父div.

在Chrome中:

在此输入图像描述

在Firefox中:

在此输入图像描述

正如您在屏幕截图中看到的,我有两次出现此问题,一次出现在左侧面板中,另一次出现在右侧面板中.在Chrome中,子div的高度保持不变,出现滚动条,并且不会超出父级的高度.在Firefox中,滚动条不会出现,并且子div的高度会增加并超过其父级.

我已经在SO上查看了一些其他类似的问题,并且在很多情况下设置min-height:0属性解决了Firefox中的问题.但是我试过加入min-height:0父母,孩子,父母和孩子,没有运气.

请在Chrome和Firefox中运行下面的代码段,以查看两种浏览器的不同之处.

我很感激有关如何防止儿童成长的任何建议.

(注意正在使用Bootstrap 4.代码片段引用了bootstrap 4 .css文件CDN)

代码片段:

.body-content {
        height: 300px;   
        max-height:100%;
        border: 3px dashed purple;
        display:flex;                       
        flex-direction: column;             
    }


#messagescontainerrow {
        flex: 1;
        border: 5px double black;
    }

#leftdiv {
        display:flex;
        flex-direction:column;
        border: 1px solid green;
    }

#messagetools {
        height: 50px;
        background-color: cornsilk;
    }

#messagelist {
        flex:1;     
        overflow-y: scroll;   
        background-color:whitesmoke;
    }

#rightdiv {
        display:flex;
        flex-direction:column;
        border: 1px solid blue;
    }

#messagesenderspane {
        width: 100%;
        height: 50px;
        background-color: lemonchiffon
    }

#messagecontents {
        flex: 1;
        overflow-y: scroll; 
        width: 100%;
        border: 1px solid blue;
        background-color: aliceblue;
    }

#messagesend {
        width: 100%;
        height: 70px;
        background-color: whitesmoke;
    }
Run Code Online (Sandbox Code Playgroud)
<html>
  <head>
  <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.2/css/bootstrap.min.css" rel="stylesheet"/>
  </head>
  <body>
    <div class="container body-content">
      <div class="row" id="messagescontainerrow">

        <div class="col-5" id="leftdiv">
            <div id="messagetools">
                <input type="button" id="newbutton" value="My Button" />
            </div>
            <div id="messagelist">
              <h4>Chat 1</h4>
              <h4>Chat 2</h4>
              <h4>Chat 3</h4>
              <h4>Chat 4</h4>
              <h4>Chat 5</h4>
              <h4>Chat 6</h4>
              <h4>Chat 7</h4>
              <h4>Chat 8</h4>
            </div>
        </div>


        <div class="col-7" id="rightdiv">
            <div id="messagesenderspane">
              Chat 3
            </div>
            <div id="messagecontents">
              <h4>line 1</h4>
              <h4>line 2</h4>
              <h4>line 3</h4>
              <h4>line 4</h4>
              <h4>line 5</h4>
              <h4>line 6</h4>
              <h4>line 7</h4>
            </div>
            <div id="messagesend">
                <textarea id="sendbox"></textarea>
                <input type="button" id="sendbutton" value="Send" />
            </div>
        </div>



      </div>
    </div>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

Mic*_*l_B 10

简答

而不是flex: 1,使用flex: 1 1 1px.

在代码中进行以下两项调整:

#messagelist {
        /* flex:1; */
        flex: 1 1 1px; /* new */
    }

#messagecontents {
        /* flex:1; */
        flex: 1 1 1px; /* new */
    }
Run Code Online (Sandbox Code Playgroud)

修改后的codepen


说明

在大多数情况下,正如您所指出的那样,min-height: 0在列方向容器中添加flex项就足以纠正问题.

然而,在这种情况下,还有一个障碍:flex-basis.

你申请以下规则弯曲项目#messagelist#messagecontents:flex: 1.

这是一个简写规则,分为:

  • flex-grow: 1
  • flex-shrink: 1
  • flex-basis: 0

(来源:https://www.w3.org/TR/css-flexbox-1/#flex-common)

在Chrome中,flex-basis: 0足以触发溢出,从而生成滚动条.

但是,在Firefox和Edge中,零flex-basis是不够的.在MDN声明的标准合规性方面,这可能是更正确的行为:

为了overflow产生效果,块级容器必须具有设置高度(heightmax-height)或white-space设置为nowrap.

好吧,flex-basis: 0不满足这些条件,因此不应发生溢出情况.Chrome可能正在进行干预(他们经常这样做).

干预是指用户代理决定稍微偏离标准化行为以提供极大增强的用户体验.

为了满足"标准化行为",这将使Firefox和Edge中出现溢出,给出flex-basis一个固定的高度(即使它只是1px).


Gar*_*ary 7

我将 Michael_B 的答案标记为正确答案,因为它是一个有效的解决方案以及一个解释。另外这里是我想出的另一个解决方案,它不需要修改 flex-basis:

#messagescontainerrow {
        flex: 1;

        min-height: 0;   /* ADDED THIS. */

        border: 5px double black;
    }

#leftdiv {
        display:flex;
        flex-direction:column;

        max-height: 100%; /* ADDED THIS */

        border: 1px solid green;
    }

#rightdiv {
        display:flex;
        flex-direction:column;

        max-height: 100%; /* ADDED THIS */

        border: 1px solid blue;
    }
Run Code Online (Sandbox Code Playgroud)

解释:

根据当前的 Flexbox 规范https://www.w3.org/TR/css-flexbox-1/#min-size-auto

通常,弹性项目的自动最小尺寸是其内容尺寸和其指定尺寸中的较小者。但是,如果框具有纵横比且未指定大小,则其自动最小大小为其内容大小和传输大小中的较小者。如果框既没有指定的尺寸也没有纵横比,它的自动最小尺寸就是内容尺寸。

因此,默认情况下 #messagescontainerrow 根据其内容采用最小高度,而不是考虑其父 flexbox 的高度。可以通过设置来覆盖此行为min-height:0

通过进行此更改,可以看到下图中显示的内容;请注意,@messagescontainerrow - 带有双线边框的那个 - 现在与其父级的高度相同 - 带有紫色虚线边框的那个。

在此处输入图片说明

(请注意,在此处找到的最新草案规范 - https://drafts.c​​sswg.org/css-flexbox/#min-size-auto - 说“对于滚动容器,自动最小尺寸为零”。所以在未来我们可能不需要这样做)。

现在剩下的是它的子代#leftdiv 和#rightdiv 的问题,它们溢出了它的边界。正如 Michael_B 指出的那样,overflow需要存在一个heightormax-height属性。所以下一步是添加max-height: 100%到#leftdiv 和#rightdiv,这样overflow-y:scroll他们的孩子的属性就会被触发。

结果如下: 在此处输入图片说明