防止弹性项目超过父级高度并使滚动条正常工作 [英] Prevent flex item from exceeding parent height and make scroll bar work

查看:77
本文介绍了防止弹性项目超过父级高度并使滚动条正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何防止带有滚动条和flex:1的子div超过Firefox中其父级flexbox的高度?它可以在Chrome中正常工作.

How can I prevent a child div with scrollbars and flex:1 from exceeding the height of its parent flexbox in Firefox? It works correctly in Chrome.

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

CodePen link (if you prefer it to Stack Overflow snippets): https://codepen.io/garyapps/pen/ZMNVJg

详细信息:

我有一个固定高度的伸缩式容器.它具有flex-direction:column设置,并且包含多个子级div,这些子级div将垂直堆叠.子div之一被赋予flex:1属性,而其他div被赋予固定高度.

I have a flex container of fixed height. It has a flex-direction:column setting, and it contains multiple childen divs which will get vertically stacked. One of the child divs is given a flex:1 property, whereas others are given fixed heights.

我期望具有flex:1属性的子div将扩展为填充剩余的垂直空间.这按预期工作.

My expectation is that the child div with the flex:1 property will expand to fill the remaining vertical space. This works as expected.

我还为子div赋予了一个overflow-y:scroll属性,以便如果其中的内容超过其高度,则会显示滚动条.在Chrome中可以正常使用.但是,在Firefox中,这个孩子的身高增加了,超过了其父div.

I have also given the child div an overflow-y:scroll property, so that if the content within it exceeds its height, scrollbars appear. This works fine in Chrome. In Firefox however, this child's height increases, exceeding its parent div.

在Chrome中:

在Firefox中:

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

As you see in the screenshot, I have two occurrences of this issue, once in the panel on the left, and the other in the panel on the right. In Chrome, the height of the child div remains constant, scrollbars appear, and the height of the parent does not get exceeded. In Firefox scrollbars do not appear, and the height of the child div increases and exceeds its parent.

我还研究了SO上的其他类似问题,在许多情况下,设置min-height:0属性可以解决Firefox中的问题.但是我尝试将min-height:0添加到父母,子女,父母和子女,但没有运气.

I have looked at a few other similar questions on SO, and in many cases setting a min-height:0 property solved the problem in Firefox. However I have tried adding min-height:0 to parents, children, both parents and children, and had no luck.

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

Please run the code snippet below in both Chrome and Firefox to see the difference in the two browsers.

对于如何防止儿童div成长的任何建议,我将不胜感激.

I would appreciate any advice on how to prevent child div from growing.

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

(Note that Bootstrap 4 is being used. The code snippet references the bootstrap 4 .css file 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>

推荐答案

简短回答

使用flex: 1 1 1px代替flex: 1.

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

Make these two adjustments in your code:

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

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

修订后的代码笔

在大多数情况下,正如您已经指出的那样,在列方向容器中添加min-height: 0来伸缩项目足以解决此问题.

In most cases, as you have noted, adding min-height: 0 to flex items in a column-direction container is enough to correct the problem.

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

In this case, however, there's an additional obstacle: flex-basis.

您要将以下规则应用于弹性项目#messagelist#messagecontents:flex: 1.

You're applying the following rule to flex items #messagelist and #messagecontents: flex: 1.

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

This is a shorthand rule that breaks down to:

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

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

2019更新:自从2018年发布此答案以来,Chrome的行为似乎已经改变,现在与Firefox和Edge保持一致.阅读此答案的其余部分时,请记住这一点.

2019 UPDATE: Since the posting of this answer in 2018, it appears that Chrome's behavior has changed and is now uniform with Firefox and Edge. Please keep that in mind as you read the rest of this answer.

在Chrome中,flex-basis: 0足以触发溢出,从而生成滚动条. ( 2019更新: 可能不再是这种情况.)

In Chrome, flex-basis: 0 is enough to trigger an overflow, which generates the scrollbars. (2019 update: This may no longer be the case.)

但是,在Firefox和Edge中,零flex-basis是不够的.从 MDN声明

In Firefox and Edge, however, a zero flex-basis is insufficient. This is probably the more correct behavior in terms of standards compliance as MDN states:

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

In order for overflow to have an effect, the block-level container must have either a set height (height or max-height) or white-space set to nowrap.

那么,flex-basis: 0都不满足这些条件,因此不应发生溢出条件. Chrome可能参与了 干预 (

Well, flex-basis: 0 meets none of those conditions, so an overflow condition should not occur. Chrome has probably engaged in an intervention (as they often do).

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

An intervention is when a user agent decides to deviate slightly from a standardized behavior in order to provide a greatly enhanced user experience.

要满足标准行为",这将使Firefox和Edge中发生溢出,请给flex-basis一个固定的高度(即使只有1像素).

To meet the "standardized behavior", which would enable an overflow to occur in Firefox and Edge, give flex-basis a fixed height (even if it's just 1px).

这篇关于防止弹性项目超过父级高度并使滚动条正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆