如何让 DIV 填满父容器的可用高度,并在内容溢出时滚动?
要让 .inner 在内容过多时滚动,需要先限制它的高度。当前 .row 的高度由两列内容共同决定,右侧内容越多,整行就越高,因而无法形成预期的滚动区域。
如果希望整行高度随左侧内容变化、右侧填满这个高度,可以将右侧 .inner 绝对定位在 .box 内,让它的内容不再参与整行高度的计算。
为什么原来的设置没有生效
overflow-y: auto 和 overflow-y: scroll 只决定内容溢出后如何处理,不会限制元素的高度。
原来的布局中:
.row没有高度约束,会随内容增高。- 两个
.col都参与整行高度的计算,左列的高度不会自动成为右列的高度上限。 .inner的flex: 1用来分配父容器的剩余空间,不能单独限制高度。
min-height: 0 允许 Flex 项目缩小到内容所需高度以下,但布局中得先有高度限制。只给 .inner 添加这条规则,祖先元素仍然会被内容撑高。
按左侧内容决定高度
让两列保持在同一条 Flex 行中,通过 align-items: stretch 等高。将右侧 .box 设为定位包含块,再让 .inner 通过绝对定位填满其中的空间。
用下面的 CSS 替换原样式,并给 HTML 中的右列加上 col--scroll 类。
.row,
.col,
.box,
.inner {
box-sizing: border-box;
}
.row {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: stretch;
gap: 0.5em;
}
.col {
display: flex;
flex: 1 1 0;
flex-direction: column;
min-width: 0;
min-height: 0;
gap: 0.5em;
border: 1px solid #000;
padding: 0.5em;
}
.box {
display: flex;
flex-direction: column;
flex: 1 1 auto;
min-height: 0;
border: 1px solid #000;
padding: 0.5em;
}
/* 右侧滚动区域的定位包含块 */
.col--scroll .box {
position: relative;
}
.inner {
position: absolute;
inset: 0.5em;
overflow-y: auto;
border: 1px solid #000;
padding: 0.5em;
}
<div class="row">
<div class="col">
<div class="box">
text. <br><br>
text. <br><br>
text. <br><br>
text.
</div>
</div>
<div class="col col--scroll">
<div class="box">
<div class="inner">
text. <br><br>
text. <br><br>
text. <br><br>
text. <br><br>
text. <br><br>
text. <br><br>
text. <br><br>
text.
</div>
</div>
</div>
</div>
右侧 .inner 脱离正常文档流后,内部的文本或图片就不会再撑高 .row。整行高度由左侧内容决定,右侧 .col 随之拉伸,.box 再填满右列。
inset: 0.5em 同时设置上、右、下、左四个方向的偏移,让 .inner 填满 .box 内部并保留间距。使用绝对定位后,.inner 就不需要 flex: 1 了。
窗口变窄、左侧文本换行时,整行高度会重新计算,右侧滚动区域也会随之调整,无须写死像素高度。
如果高度由视口或外层布局提供
如果希望左右两列都填满页面中的某个区域,可以继续使用纯 Flex 布局。保留原始 HTML,改用下面这套独立样式,无须设置绝对定位:
.row {
display: flex;
gap: 0.5em;
height: 70dvh; /* 示例:高度由视口提供 */
}
.col {
display: flex;
flex: 1 1 0;
flex-direction: column;
min-width: 0;
min-height: 0;
border: 1px solid #000;
padding: 0.5em;
}
.box {
display: flex;
flex: 1 1 0;
flex-direction: column;
min-height: 0;
border: 1px solid #000;
padding: 0.5em;
}
.inner {
flex: 1 1 0;
min-height: 0;
overflow-y: auto;
border: 1px solid #000;
padding: 0.5em;
}
70dvh 只是高度约束的示例,具体值应按页面布局调整。如果外层已经通过 Flex 或 Grid 分配了可用高度,就沿用这部分空间,并检查中间需要收缩的 Flex 项目是否设置了 min-height: 0。
这种方案的高度由视口或外层布局决定,不会随左侧内容自然增长。
使用时注意
- 两列需要在同一行。原来的
.row { flex-wrap: wrap; }允许列换行,而不同 Flex 行之间不会自动同步高度。如果窄屏时需要上下排列,应另外给滚动区域设置高度或最大高度。 overflow-y: auto在需要时提供滚动;scroll始终请求纵向滚动条,具体显示方式受系统设置影响。两者都无法解决缺少高度约束的问题。- 单独设置
height: 100%通常无法解决这个示例的问题,因为父级高度仍由内容决定,不能据此限制子元素的高度。 - 第一种方案适用于右侧
.box内只有滚动区域的结构。如果还要放标题或工具栏,应为这些正常流内容预留空间,避免绝对定位的.inner覆盖它们。
备注:内容仅供参考。
