如何防止带有滚动条和flex:1
的子div超过Firefox中其父级flexbox的高度?它可以在Chrome中正常工作。
CodePen链接(如果您更喜欢Stack Overflow片段): https://codepen.io/garyapps/pen/ZMNVJg
详细信息:
我有一个固定高度的伸缩容器。它具有flex-direction:column
设置,并且包含多个子级div,这些子级div将垂直堆叠。子div之一被赋予flex:1
属性,而其他div被赋予固定高度。
我期望具有flex:1
属性的子div将扩展为填充剩余的垂直空间。这按预期工作。
我还为子div赋予了overflow-y:scroll
属性,以便如果其中的内容超出其高度,则会显示滚动条。在Chrome中可以正常使用。但是,在Firefox中,这个孩子的身高增加了,超过了其父div。
在Chrome中:
在Firefox中:
如您在屏幕快照中所见,我有两次出现此问题,一次出现在左侧面板中,另一次出现在右侧面板中。在Chrome浏览器中,子div的高度保持不变,出现滚动条,并且父子的高度未超过。在Firefox中,滚动条不会出现,并且子div的高度会增加并超过其父项。
我还研究了SO上的其他一些类似问题,在许多情况下,设置min-height:0
属性可以解决Firefox中的问题。但是,我尝试将min-height:0
添加到父母,子女(包括父母和子女),但没有运气。
请在Chrome和Firefox中运行下面的代码段,以查看两种浏览器之间的区别。
对于如何防止儿童div成长的任何建议,我将不胜感激。
(请注意,正在使用Bootstrap4。代码段引用了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;
}
<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>
答案 0 :(得分:6)
使用flex: 1
代替flex: 1 1 1px
。
在代码中进行以下两项调整:
#messagelist {
/* flex:1; */
flex: 1 1 1px; /* new */
}
#messagecontents {
/* flex:1; */
flex: 1 1 1px; /* new */
}
在大多数情况下,正如您已经提到的,添加min-height: 0
来伸缩列方向容器中的项目就足以解决问题。
但是,在这种情况下,还有一个障碍: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 states而言,这可能是更正确的行为:
为了使
overflow
生效,块级容器必须具有设置的高度(height
或max-height
)或white-space
设置为{{ 1}}。
嗯,nowrap
不满足那些条件,因此不应发生溢出条件。 Chrome可能参与了 intervention (as they often do)。
干预是指用户代理决定稍微偏离标准行为以提供大大增强的用户体验。
要满足“标准行为”(这将使Firefox和Edge中发生溢出),请将flex-basis: 0
设置为固定高度(即使只有1像素)。
答案 1 :(得分:3)
我将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;
}
说明:
按照当前的Flexbox规范https://www.w3.org/TR/css-flexbox-1/#min-size-auto
通常,弹性商品的自动最小尺寸越小 其内容大小和指定大小。但是,如果盒子上有一个 宽高比且未指定尺寸,其自动最小尺寸为 其内容大小和传输大小中的较小者。如果盒子有 既不是指定的尺寸也不是长宽比,它的自动最小值 size是内容的大小。
因此,默认情况下,#messagescontainerrow根据其内容采用最小高度,而不是考虑其父级flexbox的高度。可以通过设置min-height:0
来覆盖此行为。
通过进行此更改,可以看到下图中显示的内容;请注意,@ messagescontainerrow(带有双线边框的边框)现在与父对象的高度相同(带有紫色虚线边框的边框)。
(请注意,最新的规范草案位于https://drafts.csswg.org/css-flexbox/#min-size-auto中,它表示“对于滚动容器,自动最小尺寸为零。因此将来我们可能不需要这样做。)
现在剩下的问题是它的子级#leftdiv和#rightdiv越过边界。正如Michael_B所指出的,overflow
要求存在height
或max-height
属性。因此,下一步是将max-height: 100%
添加到#leftdiv和#rightdiv中,以便触发其子级的overflow-y:scroll
属性。