- 首页
- 前端开发
- 具有两个等高子项的 Flexbox 布局,其中一个包含带有滚动内容的嵌套 Flexbox
具有两个等高子项的 Flexbox 布局,其中一个包含带有滚动内容的嵌套 Flexbox
[英] Flexbox layout with two equal height children, one containing nested flexbox with scrolling content
本文介绍了具有两个等高子项的 Flexbox 布局,其中一个包含带有滚动内容的嵌套 Flexbox的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一个 <img>
,它的右侧有一个面板,其中包含一个控件标题和一长串项目.所以我有一个嵌套的 flexbox 情况:
.container (flex)->.child img->.child 控制面板 (flex)->.controls->.content-wrapper 滚动列表
在非常基本的层面上,两个并排的面板很容易,使用 align-items:stretch
成为一个简单的 flex .. https://codepen.io/neekfenwick/pen/MOxYxz
在那个基本层面,这是一个重复的问题 如何让两个并排的 div 保持相同的高度?.
一旦右侧的面板因垂直滚动列表而变得更加复杂,我无法看到如何使其父级的高度,即第二个 .child
的高度与第一个 的高度匹配>.child
.https://codepen.io/neekfenwick/pen/XzGJGw
+-------------+---------------+||控制 ||左子 |||+--------------+||A|||垂直 |+||滚动 ||||项目 |||||+||V|+--------------+--------------+
我已阅读具有可滚动内容的 Flexbox 项目,但这解决了水平滚动问题,不是这样的垂直布局.另外 带滚动区域的嵌套 flexbox 处理垂直堆叠的嵌套 flexbox,我认为这种组合row
和 column
方向混淆了我的情况.
作为代码片段:
.container {显示:弹性;对齐项目:拉伸;}.孩子 {边框:1px 纯灰色;背景颜色:浅灰色;弹性:1 1 自动;}.控制面板{显示:弹性;弹性方向:列;}.controls {弹性:0 0 自动;}.content-wrapper {弹性:1 1 自动;宽度:400px;溢出-y:自动;}.content-item {显示:内联块;宽度:100px;高度:100px;背景颜色:红色;}
<div class="child"><p>在现实生活中,我是一个内嵌的 img.</p><p>我有点内容呲牙咧嘴.</p><p>我有点内容呲牙咧嘴.</p><p>我有点内容呲牙咧嘴.</p><p>我希望我的兄弟姐妹和我一样高.</p>
<div class="子控件面板"><div class="控件"><p>小控制区域.下面的面板应垂直滚动.</p>
<div class="content-wrapper"><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div>
我不想在这里固定任何元素的高度.碰巧,我知道 img 的高度,所以我可以使用 CSS 来强制右侧元素的高度,但我想知道是否有一种真正的"flexbox 方法可以解决这个问题.
解决方案
一般来说,对于 overflow: scroll
(或 auto
和 hidden
) 工作,需要以一种或另一种方式进行高度约束,否则元素通常会根据需要增长以适应其内容.
主要有 3 种方式,其中一种是设置实际高度,如在第一个示例中,我将其添加到 container
.
堆栈片段 1
.container {显示:弹性;高度:100vh;}.孩子 {边框:1px 纯灰色;背景颜色:浅灰色;弹性:1 1 自动;}.控制面板{显示:弹性;弹性方向:列;}.controls {弹性:0 0 自动;}.content-wrapper {弹性:1 1 自动;宽度:400px;溢出-y:自动;}.content-item {显示:内联块;宽度:100px;高度:100px;背景颜色:红色;}
<div class="child"><p>在现实生活中,我是一个内嵌的 img.</p><p>我有点内容呲牙咧嘴.</p><p>我有点内容呲牙咧嘴.</p><p>我有点内容呲牙咧嘴.</p><p>我希望我的兄弟姐妹和我一样高.</p>
<div class="子控件面板"><div class="控件"><p>小控制区域.下面的面板应垂直滚动.</p>
<div class="content-wrapper"><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div>
<小时>或者使用绝对定位来创建高度约束,这是绝对元素所做的.
它只是通过一个额外的包装器实现,content-scroll
,并将保持结构的其余部分完全动态.
堆栈片段 2
.container {显示:弹性;}.孩子 {边框:1px 纯灰色;背景颜色:浅灰色;弹性:1 1 自动;}.控制面板{显示:弹性;弹性方向:列;}.controls {弹性:0 0 自动;}.content-wrapper {位置:相对;弹性:1 1 自动;宽度:400px;}.内容滚动{位置:绝对;顶部:0;左:0;右:0;底部:0;溢出-y:自动;}.content-item {显示:内联块;宽度:100px;高度:100px;背景颜色:红色;}
<div class="child"><p>在现实生活中,我是一个内嵌的 img.</p><p>我有点内容呲牙咧嘴.</p><p>我有点内容呲牙咧嘴.</p><p>我有点内容呲牙咧嘴.</p><p>我希望我的兄弟姐妹和我一样高.</p>
<div class="子控件面板"><div class="控件"><p>小控制区域.下面的面板应垂直滚动.</p>
<div class="content-wrapper"><div class="content-scroll"><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div>
<小时>单独使用 Flexbox,认为它可能无法完全跨浏览器工作,尤其是旧版本,仍然支持它,但有很多错误.
原始代码中的简单修复是将 .content-wrapper
中的 flex: 1 1 auto;
更改为 flex: 1 1 0px;
(我的 IE 版本需要 0px
,Chrome/Firefox/Edge 可以使用 0
)
堆栈片段 3
.container {显示:弹性;}.孩子 {边框:1px 纯灰色;背景颜色:浅灰色;弹性:1 1 自动;}.控制面板{显示:弹性;弹性方向:列;}.controls {弹性:0 0 自动;}.content-wrapper {弹性:1 1 0px;宽度:400px;溢出-y:自动;}.content-item {显示:内联块;宽度:100px;高度:100px;背景颜色:红色;}
<div class="child"><p>在现实生活中,我是一个内嵌的 img.</p><p>我有点内容呲牙咧嘴.</p><p>我有点内容呲牙咧嘴.</p><p>我有点内容呲牙咧嘴.</p><p>我希望我的兄弟姐妹和我一样高.</p>
<div class="子控件面板"><div class="控件"><p>小控制区域.下面的面板应垂直滚动.</p>
<div class="content-wrapper"><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div><div class="content-item"></div>
<小时>代码段 2 和 3 也回答了您的问题
<块引用>...使用垂直滚动列表,我看不到如何制作其父级的高度,即第二个 .child
,与第一个 .child
.
注意,如果右列的顶部元素可以比左列更大,则底部元素需要一个最小高度,以防止其折叠为0,例如>
.content-wrapper {...最小高度:200px;/* 例如像这样 */}
I have an <img>
with a panel to its right containing a controls header and a long list of items. So I have a nested flexbox situation:
.container (flex)
-> .child img
-> .child controls panel (flex)
-> .controls
-> .content-wrapper scrolling list
At a very basic level, the two side by side panels are easy, being a simple flex with align-items: stretch
.. https://codepen.io/neekfenwick/pen/MOxYxz
At that basic level it's a duplicate question to How do I keep two divs that are side by side the same height?.
Once the panel on the right becomes more complex with a vertically scrolling list, I cannot see how to make the height of its parent, the second .child
, match the height of the first .child
. https://codepen.io/neekfenwick/pen/XzGJGw
+-------------+---------------+
| | Controls |
| Left child | |
| +---------------+
| | A|
| | Vertically |+
| | scrolling ||
| | items ||
| | |+
| | V|
+-------------+---------------+
I have read Flexbox item with scrollable content but that solves a horizontal scrolling problem, not a vertical layout like this. Also Nested flexbox with scrolling area deals with vertically stacked nested flexboxes, I think this combination of row
and column
directions confuses my situation.
As a code snippet:
.container {
display: flex;
align-items: stretch;
}
.child {
border: 1px solid grey;
background-color: lightgrey;
flex: 1 1 auto;
}
.controls-panel {
display: flex;
flex-direction: column;
}
.controls {
flex: 0 0 auto;
}
.content-wrapper {
flex: 1 1 auto;
width: 400px;
overflow-y: auto;
}
.content-item {
display: inline-block;
width: 100px;
height: 100px;
background-color: red;
}
<div class="container">
<div class="child">
<p>In real life I am an inline img.</p>
<p>I am some content whoop de doo.</p>
<p>I am some content whoop de doo.</p>
<p>I am some content whoop de doo.</p>
<p>I want my sibling to equal my height.</p>
</div>
<div class="child controls-panel">
<div class="controls">
<p>Small controls area. Panel below should scroll vertically.</p>
</div>
<div class="content-wrapper">
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
</div>
</div>
</div>
I do not want to fix the height of any elements here. As it happens, I know the height of the img, and so I could use CSS to force the height of the elements on the right, but I wondered if there is a 'true' flexbox way of solving this problem.
解决方案
In general, for overflow: scroll
(or auto
and hidden
) to work, a height constraint is needed in one way or the other, or else element's normally grow as much as needed to fit their content.
There is mainly 3 ways, where either an actual height is set, as in this first sample, where I added it to the container
.
Stack snippet 1
.container {
display: flex;
height: 100vh;
}
.child {
border: 1px solid grey;
background-color: lightgrey;
flex: 1 1 auto;
}
.controls-panel {
display: flex;
flex-direction: column;
}
.controls {
flex: 0 0 auto;
}
.content-wrapper {
flex: 1 1 auto;
width: 400px;
overflow-y: auto;
}
.content-item {
display: inline-block;
width: 100px;
height: 100px;
background-color: red;
}
<div class="container">
<div class="child">
<p>In real life I am an inline img.</p>
<p>I am some content whoop de doo.</p>
<p>I am some content whoop de doo.</p>
<p>I am some content whoop de doo.</p>
<p>I want my sibling to equal my height.</p>
</div>
<div class="child controls-panel">
<div class="controls">
<p>Small controls area. Panel below should scroll vertically.</p>
</div>
<div class="content-wrapper">
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
</div>
</div>
</div>
Or to use absolute positioning to create that height constraint, which an absolute element does.
It is simply accomplished with an extra wrapper, content-scroll
, and will keep the rest of the structure fully dynamic.
Stack snippet 2
.container {
display: flex;
}
.child {
border: 1px solid grey;
background-color: lightgrey;
flex: 1 1 auto;
}
.controls-panel {
display: flex;
flex-direction: column;
}
.controls {
flex: 0 0 auto;
}
.content-wrapper {
position: relative;
flex: 1 1 auto;
width: 400px;
}
.content-scroll {
position: absolute;
top: 0; left: 0;
right: 0; bottom: 0;
overflow-y: auto;
}
.content-item {
display: inline-block;
width: 100px;
height: 100px;
background-color: red;
}
<div class="container">
<div class="child">
<p>In real life I am an inline img.</p>
<p>I am some content whoop de doo.</p>
<p>I am some content whoop de doo.</p>
<p>I am some content whoop de doo.</p>
<p>I want my sibling to equal my height.</p>
</div>
<div class="child controls-panel">
<div class="controls">
<p>Small controls area. Panel below should scroll vertically.</p>
</div>
<div class="content-wrapper">
<div class="content-scroll">
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
</div>
</div>
</div>
</div>
Use Flexbox alone, thought it might not work fully cross browsers, especially with older versions, that still support it but is a lot buggier.
The simple fix in your original code is to change the flex: 1 1 auto;
in .content-wrapper
to flex: 1 1 0px;
(0px
were needed for my IE version, for Chrome/Firefox/Edge one can use 0
)
Stack snippet 3
.container {
display: flex;
}
.child {
border: 1px solid grey;
background-color: lightgrey;
flex: 1 1 auto;
}
.controls-panel {
display: flex;
flex-direction: column;
}
.controls {
flex: 0 0 auto;
}
.content-wrapper {
flex: 1 1 0px;
width: 400px;
overflow-y: auto;
}
.content-item {
display: inline-block;
width: 100px;
height: 100px;
background-color: red;
}
<div class="container">
<div class="child">
<p>In real life I am an inline img.</p>
<p>I am some content whoop de doo.</p>
<p>I am some content whoop de doo.</p>
<p>I am some content whoop de doo.</p>
<p>I want my sibling to equal my height.</p>
</div>
<div class="child controls-panel">
<div class="controls">
<p>Small controls area. Panel below should scroll vertically.</p>
</div>
<div class="content-wrapper">
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
</div>
</div>
</div>
Snippet 2 and 3 also answers your question
...with a vertically scrolling list, I cannot see how to make the
height of its parent, the second .child
, match the height of the
first .child
.
Note, if the top element in the right column can grow bigger than the left column, a minimum height will be needed on the bottom element, to prevent it from collapse into 0, e.g.
.content-wrapper {
...
min-height: 200px; /* e.g. like this */
}
这篇关于具有两个等高子项的 Flexbox 布局,其中一个包含带有滚动内容的嵌套 Flexbox的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文