如何防止带有滚动条和flex:1
的子div在Firefox中超过其父flexbox的高度?它在Chrome中正常工作。
CodePen链接(如果您喜欢它来堆叠溢出代码段):https://codepen.io/garyapps/pen/ZMNVJg
细节:
我有一个固定高度的柔性容器。它有一个flex-方向:列
设置,它包含多个垂直堆叠的Childen div。其中一个子div被赋予一个flex: 1
属性,而其他div被赋予固定的高度。
我期望具有flex:1
属性的子div将扩展以填充剩余的垂直空间。这正如预期的那样有效。
我还为child div提供了一个overflow-y:scroll
属性,这样,如果其中的内容超过其高度,就会出现滚动条。这在铬上很好用。然而,在Firefox中,这个孩子的身高增加了,超过了它的父div。
在Chrome:
在Firefox中:
正如你在屏幕截图中看到的,我有两次出现这个问题,一次在左边的面板中,另一次在右边的面板中。在Chrome中,子div的高度保持不变,出现滚动条,父div的高度不会超过。在Firefox中不会出现滚动条,并且子div的高度会增加并超过其父div。
我已经研究了其他一些类似的问题,在很多情况下,设置minheight:0
属性解决了Firefox中的问题。然而,我尝试将min height:0
添加到父母、孩子、父母和孩子身上,但没有成功。
请在Chrome和Firefox中运行下面的代码片段,查看这两种浏览器的区别。
如果您能就如何防止儿童div的生长提出建议,我将不胜感激。
(注意正在使用Bootstrap 4。代码片段引用了引导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>
我认为Michael_B的答案是正确的,因为这是一个有效的解决方案,并附有解释。此外,我还提出了另一个解决方案,它不需要修改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;
}
说明:
根据当前Flexbox规范https://www.w3.org/TR/css-flexbox-1/#min-size-auto
通常,弹性项的自动最小大小是其内容大小和指定大小中的较小者。但是,如果长方体具有纵横比且没有指定大小,则其自动最小大小为其内容大小和传输大小中的较小者。如果框既没有指定的大小也没有纵横比,则其自动最小大小为内容大小。
因此,默认情况下,messagescontainerrow根据其内容采用最小高度,而不是考虑其父flexbox的高度。可以通过设置最小高度:0
来覆盖此行为。
通过进行此更改,可以看到下图中显示的内容;请注意@messagescontainerrow(带双线边框的)现在与其父级(带紫色虚线边框的)的高度相同。
(请注意,最新的规范草案,见下文-https://drafts.csswg.org/css-flexbox/#min-大小自动-表示“对于滚动容器,自动最小大小为零”。因此,将来我们可能不需要这样做)。
现在剩下的是它的孩子#leftdiv和#rightdiv的问题,溢出了它的边界。正如Michael_B指出的,overflow
需要一个高
或max-高
属性。因此,下一步是向#leftdiv和#rightdiv添加max-high: 100%
,从而触发其子级的overflow-y: scroll
属性。
使用flex:1 1px
代替flex:1
。
在代码中做这两个调整:
#messagelist {
/* flex:1; */
flex: 1 1 1px; /* new */
}
#messagecontents {
/* flex:1; */
flex: 1 1 1px; /* new */
}
修正编码笔
在大多数情况下,正如您所指出的,向列方向容器中的flex项添加min-high: 0
就足以纠正问题。
然而,在这种情况下,还有一个障碍:flex-basis
。
您正在将以下规则应用于弹性项#messagelist
和#messagecontents
:flex:1
。
这是一条速记规则,可分解为:
flex-grow:1
(来源:https://www.w3.org/TR/css-flexbox-1/#flex-(普通)
2019年更新:自2018年发布这个答案以来,铬的行为似乎已经改变,现在与火狐和边缘保持一致。当你阅读剩下的答案时,请记住这一点。
在Chrome中,flex-base: 0
足以触发溢出,从而生成滚动条。
然而,在Firefox和Edge中,零灵活基础是不够的。正如MDN所说,这可能是标准合规性方面更正确的行为:
为了使overflow
产生效果,块级容器必须具有设置的高度(高
或max-高
)或白空间
设置为now rap
。
那么,flex-base: 0
不满足这些条件,所以不应该出现溢出条件。Chrome可能参与了干预(就像他们经常做的那样)。
干预是指用户代理决定稍微偏离标准化行为,以提供大大增强的用户体验。
为了满足标准化行为,这将使溢出发生在Firefox和Edge中,给flex-base
一个固定的高度(即使它只有1px)。
问题内容: 我有以下对象的“树”: 当使用鼠标滚轮在外部JScrollPane上滚动时,遇到一个令人讨厌的问题。一旦鼠标光标触摸到内部JScrollPane,滚动事件似乎就会传递到该JScrollPane中,并且第一个事件不再对其进行处理。这意味着停止滚动“父” JScrollPane。 是否可以 仅 禁用内部JScrollPane上的鼠标滚轮?甚至更好的是,如果没有要滚动的内容(大多数情况下,文
我试图找出如何使列表中的最后一个flex项不扩展到容器的底部。它有一个contenteditable div,当有人输入多行文本时,我需要将其展开。 主要的灵活项目是一列中的3个div,标题栏宽度为100%,内容容器宽度为100%,有增长和收缩,页脚是灵活的,应该会导致内部容器收缩。 目前,当你在div.detail聊天输入中输入多行文本时,它确实会向上扩展,但也会向下推按钮。 这样地:
我有一个居中的flexbox结构,显示客户列表框。 我想实现的是,当屏幕变得比div中的内容更窄时,它不会隐藏在视口之外,而是将溢出添加到最长的项目,即with table,因此可以动态收缩。 当我将添加到中时,它的工作原理应该是一样的,但我不希望框的全屏宽度至少达到内容的大小。 |JSFIDDLE演示| 1-全屏窗口 2-调整大小(更小)的窗口 3-调整大小(更小)的窗口-所需结果
问题内容: 我有这个HTML结构: 我想在主体部分(#body)中包含三个部分而不会溢出。因此,我需要在中间部分使用滚动条。 我尝试了这个CSS: 和这个: 但是它们都不起作用。 我在JSFiddle上做了一个例子。 我可以仅使用CSS和HTML来做到这一点吗?我宁愿避免使用Javascript。 问题答案: Flexbox是一种现代替代方案,可让您无需固定高度或JavaScript即可执行此操作
问题内容: 我在尝试将.html页面在Chrome上保持一致的宽度时遇到一个小问题,例如,我的页面(1)的内容很多,导致视口(正确的单词?)高度溢出,因此有一个垂直滚动条在该页面上(1)。在页面(2)上,我具有相同的布局(菜单,div,…等),但内容较少,因此其中没有垂直滚动条。 问题是,在页面(1)上,滚动条似乎将元素稍微向左推(累加了宽度?),而所有内容似乎都很好地位于页面(2)的中心 我仍然
我正在尝试在我的应用程序中实现聊天。 我写了一个自动调整离子文本区域如下:视图 CSS 指令 除了滚动,一切都很好。 当我超过100px最大高度时,我无法在ion文本区域中滚动。。。因此,如果我想纠正文本中隐藏的部分,那是不可能的。此外,当我试图滚动它实际上滚动聊天(离子内容)。。。 知道我该怎么解决这个问题吗?