代码之家  ›  专栏  ›  技术社区  ›  Gary

在Firefox中,子div高度超过flex父级高度,但在Chrome中没有

  •  3
  • Gary  · 技术社区  · 7 年前

    如何使用滚动条和 flex:1

    CodePen链接(如果您喜欢它来堆叠溢出代码段): https://codepen.io/garyapps/pen/ZMNVJg

    细节

    我有一个固定高度的弹性容器。它有一个 flex-direction:column 设置,并且它包含多个将垂直堆叠的子div。其中一个孩子得到了 flex:1 而其他人则被赋予固定的高度。

    我的期望是,孩子和孩子一起跳伞 flex:1

    我也给了孩子一个div overflow-y:scroll 属性,以便如果其中的内容超过其高度,则会显示滚动条。这在铬上很好用。但是在Firefox中,这个孩子的身高增加了,超过了它的父div。

    镀铬:

    enter image description here

    enter image description here

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

    我已经看了其他一些类似的问题,所以,在许多情况下,设置一个 min-height:0 最小-height:0 对父母,对孩子,对父母和孩子,都没有运气。

    请在Chrome和Firefox中运行下面的代码片段,看看这两种浏览器的区别。

    如果您能给我一些建议,我将不胜感激。

    (请注意,正在使用引导4。代码段引用了bootstrap4.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;
        }
    <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>
    2 回复  |  直到 6 年前
        1
  •  25
  •   Michael Benjamin William Falcon    6 年前

    简短的回答

    flex: 1 flex: 1 1 1px .

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

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

    revised codepen


    解释

    min-height: 0 在列方向容器中调整项就足以解决问题。

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

    #messagelist #messagecontents 弹性:1 .

    这是一个速记规则,可分解为:

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

    https://www.w3.org/TR/css-flexbox-1/#flex-common


    2019年更新: 自2018年发布这一答案以来,Chrome的行为似乎发生了变化,现在已经与Firefox和Edge保持一致。请记住这一点,因为你读这个答案的其余部分。


    弹性基础:0 2019年更新: This may no longer be the case .)

    然而,在Firefox和Edge中 伸缩基准值 MDN states

    为了 overflow height max-height white-space 设置为 nowrap .

    好, 弹性基础:0 不满足这些条件,因此不应出现溢出条件。Chrome可能参与了 intervention ( as they often do ).

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

    为了满足“标准化行为”,这将使溢出发生在Firefox和Edge中,给出 固定高度(即使只有1倍)。

        2
  •  6
  •   Gary    7 年前

    我认为迈克尔的答案是正确的,因为这是一个有效的解决方案和解释。此外,我还提出了另一个解决方案,它不需要修改flex基础:

    #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;
        }
    

    说明:

    https://www.w3.org/TR/css-flexbox-1/#min-size-auto

    通常,弹性项的自动最小大小较小 纵横比和无规定尺寸时,其自动最小尺寸为 较小的内容大小和传输的大小。如果盒子里有 既不是指定的大小,也不是宽高比,而是其自动最小值 size是内容大小。

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

    enter image description here

    (请注意,最新的规范草案- https://drafts.csswg.org/css-flexbox/#min-size-auto -表示“对于滚动容器,自动最小大小为零”。所以将来我们可能不需要这样做)。

    现在剩下的是孩子们的问题,左边的和右边的,充斥着边界。正如Michael所指出的, overflow 需要 height max-height 要存在的属性。所以下一步是 max-height: 100% overflow-y:scroll 他们孩子的财产被触发。

    结果如下: enter image description here