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

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

问题描述

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

CodePen 链接(如果您更喜欢 Stack Overflow 片段):

在 Firefox 中:

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

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

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

如果您有任何关于如何防止子 div 增长的建议,我将不胜感激.

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

代码片段:

.body-content {高度:300px;最大高度:100%;边框:3px 紫色虚线;显示:弹性;弹性方向:列;}#messagescontainerrow {弹性:1;边框:5px双黑;}#leftdiv {显示:弹性;弹性方向:列;边框:1px纯绿色;}#messagetools {高度:50px;背景色:玉米须;}#messagelist {弹性:1;溢出-y:滚动;背景颜色:whitesmoke;}#rightdiv {显示:弹性;弹性方向:列;边框:1px纯蓝色;}#messagesenderspane {宽度:100%;高度:50px;背景色:柠檬雪纺}#消息内容{弹性:1;溢出-y:滚动;宽度:100%;边框:1px纯蓝色;背景颜色:aliceblue;}#messagesend {宽度:100%;高度:70px;背景颜色:whitesmoke;}

<头><link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.2/css/bootstrap.min.css" rel="stylesheet"/><身体><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="我的按钮"/>

<div id="消息列表"><h4>聊天1</h4><h4>聊天2</h4><h4>聊天3</h4><h4>聊天4</h4><h4>聊天5</h4><h4>聊天6</h4><h4>聊天7</h4><h4>聊天8</h4>

<div class="col-7" id="rightdiv"><div id="messagesenderspane">聊天 3

<div id="消息内容"><h4>第1行</h4><h4>第2行</h4><h4>第3行</h4><h4>第4行</h4><h4>第5行</h4><h4>第6行</h4><h4>第7行</h4>

<div id="messagesend"><textarea id="sendbox"></textarea><input type="button" id="sendbutton" value="发送"/>

</html>

解决方案

简答

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

在您的代码中进行这两项调整:

#messagelist {/* 弹性:1;*/弹性:1 1 1px;/* 新的 */}#消息内容{/* 弹性:1;*/弹性:1 1 1px;/* 新的 */}

修改后的代码笔

<小时>

说明

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

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

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

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

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

<小时>

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

<小时>

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

然而,在 Firefox 和 Edge 中,零 flex-basis 是不够的.正如 MDN 所述:

<块引用>

为了让 overflow 起作用,块级容器必须有一个设置的高度(heightmax-height) 或 white-space 设置为 nowrap.

好吧,flex-basis: 0 不满足这些条件,所以不应该发生溢出条件.Chrome 可能参与了干预(他们经常这样做).

<块引用>

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

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

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 link (if you prefer it to Stack Overflow snippets): https://codepen.io/garyapps/pen/ZMNVJg

Details:

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.

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

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.

In Chrome:

In Firefox:

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.

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.

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

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

(Note that Bootstrap 4 is being used. The code snippet references the bootstrap 4 .css file CDN)

Code Snippet:

.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>

解决方案

Short Answer

Instead of flex: 1, use flex: 1 1 1px.

Make these two adjustments in your code:

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

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

revised codepen


Explanation

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.

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

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

This is a shorthand rule that breaks down to:

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


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.


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

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:

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.

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.

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天全站免登陆