一个flex/grid项目为兄弟节点设置大小限制

55

我有两个兄弟元素,它们各自包含动态内容。

<div class="flex">
    <div class="sibling-1"></div>
    <div class="sibling-2"></div>
</div>

在一些情况下,sibling-1的内容会比sibling-2更多,反之亦然。我希望第二个元素sibling-2的高度始终等于第一个sibling-1的高度。如果sibling-2的高度大于sibling-1的高度,则会溢出flex容器并可以滚动。

是否有任何方法可以使用Flexbox实现这一点?


1
基本上...不行。这不是flexbox的工作方式。你需要使用JavaScript。 - Paulie_D
1
我在这里唯一的想法是绝对定位第二个子元素。那可能有效,但它不是一个 flexbox 解决方案。 - Paulie_D
1
@Paulie_D,叹气不想这样做,但我可能不得不这样做。 - uneducatedguy
与获取更多方法相关:https://dev59.com/flUM5IYBdhLWcg3wYvTl#48943583 - Temani Afif
如果您还涉及到sticky(而不是grid),则父元素的height:0和overflow也可以完成此任务。下面是一个实时示例 ;) - G-Cyrillus
6个回答

71
是的,这是可能的。不要更改设置为最大高度的兄弟元素,而是将其他元素的flex-basis: 0flex-grow: 1进行设置,根据规范,它们会扩展到其兄弟元素的高度。无需使用绝对定位或在任何元素上设置高度。

main {
  display: flex;
}

section {
  display: flex;
  flex-direction: column;
  width: 7em;
  border: thin solid black;
  margin: 1em;
}

:not(.limiter)>div {
  flex-basis: 0px;
  flex-grow: 1;
  overflow-y: auto;
}
<main>
  <section>
    <div>I'm longer and will scroll my overflow. in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text
      in flow text in flow text in flow text in flow text in flow text in flow text in</div>
  </section>

  <section class="limiter">
    <div>Every parent's siblings match my height. in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text</div>
  </section>

  <section>
    <div>I'm shorter but still match the height. in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text in flow text</div>
  </section>
</main>


6
如果flex-direction是column,那么这个方法适用,但我认为原问题涉及到flex-direction的默认值为row。 - Sean Mackesey
2
实际上,@SeanMackesey,我认为这个可以工作是因为有额外的标记。如果您愿意在您的div周围包装另一个部分,这是一个好的解决方案。 <main>也是一行。 - Palash Karia
这个有效!我还注意到我可以将flex-grow设置为任何大于0的数字,您能解释更多吗? - Yiping
1
我创建了一个类似的问题,但它被关闭为重复问题,但实际上并不完全相同:https://stackoverflow.com/questions/66527005/how-to-have-a-vertical-scroll-bar-in-a-flex-layout-without-fixed-height 在我的情况下,我没有一个元素来限制其他元素,而是有一个元素应该由其他元素中最高的一个来限制。你能帮我吗? - Fla
@PalashKaria 您的示例在父级上使用了固定尺寸。使用固定尺寸,您可以仅通过 height: 100%; 调整子项,根本不需要此答案的神奇之处。 - stackprotector
显示剩余2条评论

21
有没有使用Flexbox实现这个的方法呢? 基本上,没有。Flex等高特性是基于容器的高度而非任何特定兄弟元素。 所以sibling-1和sibling-2总是可以具有相同的高度。 但是Flexbox没有内置机制将元素的高度限制为一个兄弟元素的高度。 可以考虑使用JavaScript或CSS定位属性。 下面是一个使用绝对定位的示例:

.flex {
  display: flex;
  width: 200px;
  position: relative;
}

.flex>div {
  flex: 0 0 50%;
  border: 1px solid black;
  box-sizing: border-box;
}

.sibling-2 {
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  right: 0;
  overflow: auto;
}
<div class="flex">
  <div class="sibling-1">text<br>text<br>text<br>text<br>text<br>text<br></div>
  <div class="sibling-2">text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br></div>
</div>

jsFiddle


2
使用Flexbox是可以实现的,第三个示例在这里展示:https://dev59.com/-6fja4cB1Zd3GeqPsz9F#47628145 - Asons
@LGSon,那是针对不同问题的答案。在这里,我们正在处理两个flex兄弟元素。而在那里,您正在处理第二列中的嵌套容器。如果您可以在没有嵌套容器的情况下使其正常工作,那么我会同意使用flex可以找到解决方案。 - Michael Benjamin
1
我会勉强同意那个 :) ... 谢谢回复 - Asons
@Michael_B 你觉得这个怎么样?我做了一个例子,减少了标记的改变(只是添加了一个非弹性父元素)https://jsfiddle.net/h7s590az/229/ - Palash Karia

3

您可以通过使兄弟元素1和2也成为弹性容器来实现此目标,然后在兄弟元素2上创建一个绝对定位的 div(也是一个弹性容器),该 div 将成为您滚动条的父容器。

<div class="sibling-1 flex sibling"></div>
<div class="sibling-2 flex sibling">
    <div class="absolute flex scroller-wrap">
        <div class="relative vertical-scroller">
            your content here
        </div> 
    </div>
</div>

CSS:

.relative{
  position:relative;
}

.absolute{
  position:absolute;
}

.flex{
  display:flex;
}

.sibling-2{
  flex:1; 
}

.scroller-wrap{
  height:100%;
}

对于兄弟元素2,只需设置最小高度为像素 - 在响应式情况下很有用,如果兄弟元素1和2在移动设备上堆叠在一起。


2
正如我在评论中提到的并在其他答案中继续讨论,没有弹性盒子方法。
不过,在第二个兄弟元素上使用position:absolute是可行的...但由于这实际上不是一个弹性盒子解决方案,所以这里仅供参考。
.flex {
  margin: 1rem auto;
  position: relative;
  display: flex;
}
.sibling-1 {
  flex: 0 0 50%;
}
.sibling-2 {
  position: absolute;
  right: 0;
  width: 50%;
  height: 100%;
  overflow: auto;
}

* {
  margin: 0;
  outline: 0;
}
.flex {
  width: 80%;
  margin: 1rem auto;
  border: 1px solid grey;
  position: relative;
  display: flex;
}
.sibling-1 {
  flex: 0 0 50%;
}
.sibling-2 {
  position: absolute;
  right: 0;
  width: 50%;
  height: 100%;
  overflow: auto;
}
<div class="flex">
  <div class="sibling-1">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore quia, voluptatum! Perspiciatis praesentium nemo, labore mollitia numquam recusandae voluptatem consectetur amet deleniti cum nesciunt blanditiis, esse quis doloremque vero! Reiciendis
      porro impedit perspiciatis. Amet in praesentium molestias ipsum ad quis quia doloribus, veniam unde, ea ducimus rerum porro tenetur voluptatem, a laudantium. Accusantium provident voluptatibus perferendis hic blanditiis laborum amet consequatur
      esse, fugiat doloremque consectetur ullam sequi, ratione perspiciatis, voluptatem eaque vitae rem repellendus in architecto vel nulla animi neque. Accusantium animi voluptatum, suscipit possimus,</p>
  </div>
  <div class="sibling-2">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eaque modi quibusdam aliquam officia illo itaque ratione, iste architecto ad blanditiis fugiat sequi laborum cupiditate voluptatum, autem non? Quibusdam ad eius hic rem id. Libero, tempora
      dicta reiciendis placeat nihil quia fuga iste aliquid quo minus labore sapiente fugit, similique non aliquam, beatae pariatur nobis fugiat! Ipsam nobis fugit maxime aliquam accusamus explicabo nostrum ab nemo adipisci dolorem qui porro ea pariatur
      corporis aut reiciendis optio, sint eum nam suscipit itaque aspernatur recusandae. Cumque qui quod doloremque. Ut voluptates, asperiores, laborum excepturi quam odit, quos rerum assumenda sapiente saepe nisi? Numquam placeat repellat eum dolorem
      reprehenderit dolores culpa id explicabo consequuntur. Quas nobis veritatis tempora animi similique earum commodi, laborum blanditiis dolor illo, eaque accusamus aliquid nam a ex, velit, maiores natus. Id totam ullam corporis. Repellat aperiam,
      distinctio maxime, dolorum illum labore recusandae. Sequi repellendus provident deserunt amet culpa, ratione dignissimos! Quibusdam delectus mollitia, ducimus. Error id architecto, ea molestias voluptate impedit inventore amet ducimus modi repellat
      in. Asperiores soluta veritatis id eius, distinctio nisi voluptates voluptatibus iste iusto error officia tempore! Ducimus sed commodi quisquam provident iure voluptatum aliquam, nobis rem dolore, consectetur, dolor rerum eum nam adipisci, libero
      beatae eaque aliquid sapiente? Eius, earum quas nostrum quasi reiciendis officia quaerat omnis. Cupiditate suscipit et tempora quibusdam perspiciatis eius cum, nisi facere animi. Delectus magnam inventore ipsum, veritatis reiciendis. Ipsum adipisci
      recusandae, similique quas labore voluptas animi eaque velit, alias eveniet qui libero obcaecati suscipit, quam nihil quos placeat.</p>
  </div>
</div>


2

从您的代码中,为了避免额外的包装,在一侧粘附,另一侧高度为0,然后在父元素上使用overflow:auto也可以使用flex来完成此工作:

示例(您将轻松理解)

.flex {
  display: flex;
  
  /* demo purpose */
  width: 500px;
  border: solid;
  overflow: auto;/* make the parent scroll */
  gap:0.5em;
}



.flex .sibling-1 {
  position: sticky;/* stick the reference for the height */
  top: 0;
}

.flex .sibling-2 {
  height: 0;/* give it no height to start from and let the parent show the scrollbar */
}
<div class="flex">
  <div class="sibling-1">
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.
      Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus
      lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor,
      facilisis luctus, metus</p>
  </div>
  <div class="sibling-2">
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.
      Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus
      lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor,
      facilisis luctus, metus</p>
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.
      Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus
      lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor,
      facilisis luctus, metus</p>
  </div>
</div>


-1

基于Lucent的答案的我简化后(至少对我来说)的代码片段:

main {
  display: flex;
  font-family: "nunito"
}

section1 {
  display: flex;
  flex-direction: column;
  width: 15rem;
  border: thin solid gray;
}

section2 {
  display: flex;
  flex-direction: column;
  width: 15rem;
  border: thin solid gray;
}

section1 > div {
  flex-basis: 0px;
  flex-grow: 1;
  overflow-y: auto;
}
<main>
  <section1 class="scroll">
    <div>I'm a div in section 1 ---
      I have extra css rules of flex-basis 0px (making me as small as possible), flex 1 (making me fill up available space), and overflow y auto (making me scroll the extra content) --- My parent section 1 is a flex column --- My grandparent main is a flex row ---</div>
  </section1>

  <section2>
    <div>I'm a div in section 2. --- My parent section 2 is a flex column --- My grandparent main is a flex row --- The height of the div in section 1 will adjust to my height.</div>
  </section2>

</main>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接