使用 flex 让一个高个子的孩子适应一个矮个子的父母

Posted

技术标签:

【中文标题】使用 flex 让一个高个子的孩子适应一个矮个子的父母【英文标题】:Fit a tall child into a shorter parent using flex 【发布时间】:2018-02-20 23:33:52 【问题描述】:

我有一个 3rd 方,可滚动,具有 100% 高度元素(我不想修改)。我想把它放在一个父 div 里面,这样它就会填满所有剩余的空间。

我曾尝试使用 Flex 来做到这一点。 (见代码 sn-p)。 我遇到的问题是,由于第 3 部分元素的内容,子 div 变得比父 div 高。 有没有办法让 flex 缩小孩子以适应父母的剩余尺寸?

编辑:如果可能的话,我想避免任何硬编码的数字,并让 flex 动态适应大小,以便 tall_child 适应剩余的父大小。

.parent 
  background-color : blue;
  height : 50vh;
  display : flex;
  flex-direction: column;



.header 
  background-color : red;
  height : 50px;
  width : 80%


.tall_child 
  background-color : green;
  width : 80%;

  /* 
  I want the height of the this child to be determined automaticlly by flex to fit remaining space of parent 
  */


.scrollable_3rd_party_element 
  height : 100%;
  overflow : scroll;
  border-style: solid;
  border-width: 5px;
<div class="parent">
  <div class="header">header</div>
  <div class="tall_child">
    <div class="scrollable_3rd_party_element">
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
    </div>
  </div>
</div>

【问题讨论】:

header的大小是否固定为50px? 没有。我试图避免使用硬编码数字,而是使用 flex 来自动增长/收缩.. 【参考方案1】:

max-height:50px 添加到.scrollable_3rd_party_element

.parent 
  background-color : blue;
  height : 100px;
  display : flex;
  flex-direction: column;



.header 
  background-color : red;
  height : 50px;
  width : 80%


.tall_child 
  background-color : green;
  width : 80%;

  /* 
  I want the height of the this child to be determined automaticlly to fit parent
  height : 50px; 
  */


.scrollable_3rd_party_element 
  height : 100%;
  overflow : scroll;
  border-style: solid;
  border-width: 5px;
  max-height: 50px
<div class="parent">
  <div class="header">header</div>
  <div class="tall_child">
    <div class="scrollable_3rd_party_element">
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
    </div>
  </div>
</div>

对于这个特定的示例父尺寸,50px 有效。但我想要 无论父母大小都可以使用的东西

那么你需要在tall_child中使用flex:1min-height: 0

我刚刚注意到它可以在 chrome 上运行,但不能在 safari 下运行 OS-X。

底部边框现在被截断,而在 chrome 中看起来很完美

Safari OSX 的快速修复是在.tall_child 中添加overflow-x:hidden 并将border.scrollable_3rd_party_element 更改为.tall_child

* 
  box-sizing: border-box


.parent 
  background-color: blue;
  height: 100px;
  display: flex;
  flex-direction: column;


.header 
  background-color: red;
  height: 50px;
  width: 80%


.tall_child 
  background-color: green;
  width: 80%;
  flex: 1;
  min-height: 0;
  /* safari fix*/
  overflow-x: hidden;
  border: 5px solid


.scrollable_3rd_party_element 
  height: 100%;
  overflow-y: scroll;

<div class="parent">
  <div class="header">header</div>
  <div class="tall_child">
    <div class="scrollable_3rd_party_element">
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
    </div>
  </div>
</div>

【讨论】:

那为什么呢? /* I want the height of the this child to be determined automaticlly to fit parent height : 50px ;*/ 和这个:.header height : 50px; 对于这个特定的示例父尺寸,50px 有效。但我想要一些不管父母大小都可以工作的东西.. 我只是忙于工作,所以当我看到 OP 的评论时我就知道该怎么做了,所以我改进/更新了答案以符合 OP 的要求。就这么简单 谢谢@dippas。在您的解决方案中,第三个元素仍然从父元素中溢出。我的目标是让它适合父母(在蓝色部分内)。因为第 3 方是可滚动的,所以我应该能够通过在绿色区域内滚动来查看所有内容。 @amit Safari OSX 的快速修复方法是在 .tall_child 中添加 overflow-x:hidden,请参阅更新后的答案【参考方案2】:

flex: 1(以允许tall_child 占用可用的垂直空间)和min-height: 0(以覆盖默认的min-height: auto)添加到.tall_child

还将box-sizing: border-box 添加到.scrollable_3rd_party_element包含高度中的border。也许使用overflow: auto 而不是scroll 会更好。

请看下面的演示:

.parent 
  background-color : blue;
  height : 50vh;
  display : flex;
  flex-direction: column;



.header 
  background-color : red;
  height : 50px;
  width : 80%


.tall_child 
  background-color : green;
  width : 80%;

  /* 
  I want the height of the this child to be determined automaticlly to fit parent
  height : 50px; 
  */
  flex: 1;
  min-height: 0;


.scrollable_3rd_party_element 
  height : 100%;
  overflow : auto;
  border-style: solid;
  border-width: 5px;
  box-sizing: border-box;
<div class="parent">
  <div class="header">header</div>
  <div class="tall_child">
    <div class="scrollable_3rd_party_element">
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
    </div>
  </div>
</div>

【讨论】:

谢谢@kukkuz。在您的解决方案中,第三个元素仍然从父元素中溢出。我的目标是让它适合父母(在蓝色部分内)。因为第 3 方是可滚动的,所以我应该能够通过在绿色区域内滚动来查看所有内容。 @amit 它适用于我的 chrome 和 firefox,你使用的是哪个浏览器? 是的。我正在使用 safari OS X。它确实适用于 chrome.. 任何想法如何使它也适用于 saferi? @amit 也许前缀是问题...例如使用-webkit-flex:1flex: 1?什么是 safari 版本? 它是版本 10.1.2 (12603.3.8)。 -webkit-flex:1 不会产生与 chrome 浏览器相同的结果【参考方案3】:

为了在没有任何固定高度元素的情况下工作,您必须至少在标题和其余元素之间保持一定比例,这不是使用 flexbox 的问题:

.parent 
  background-color : blue;
  height : 50vh;
  display : flex;
  flex-direction: column;



.header 
  background-color : red;
  height : 15%;
  width : 80%


.tall_child 
  background-color : green;
  width : 80%;
  height: 85%;


.scrollable_3rd_party_element 
  height : 100%;
  overflow-y : scroll;
  border-style: solid;
  border-width: 5px;
  box-sizing: border-box;
<div class="parent">
  <div class="header">header</div>
  <div class="tall_child">
    <div class="scrollable_3rd_party_element">
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
    </div>
  </div>
</div>

Codepen demo

【讨论】:

我想知道.. flex 能够在不“知道比例”的情况下通过使用 flex-grow 将一个较短的孩子填充到一个较大的父母中。一个高个子的孩子不能这样做吗?【参考方案4】:

另一个受How to make flexbox children 100% height of their parent?启发的选项

不完美,因为它需要修改第 3 方元素“位置”和“宽度”。但它似乎几乎适用于 chrome 和 safari(很少有像素错位)。 也许有人会发现它是另一种有用的选择。

.parent 
  background-color : blue;
  height : 50vh;
  display : flex;
  flex-direction: column;



.header 
  background-color : red;
  height : 50px;
  width : 80%


.tall_child 
  background-color : green;
  width : 80%;
  flex-grow : 1;
  position: relative;


.scrollable_3rd_party_element 
  position: absolute;
  width : 100%;
  height : 100%;
  overflow : scroll;
  border-style: solid;
  border-width: 5px;
<div class="parent">
  <div class="header">header</div>
  <div class="tall_child">
    <div class="scrollable_3rd_party_element">
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
      <div>content</div>
    </div>
  </div>
</div>

【讨论】:

以上是关于使用 flex 让一个高个子的孩子适应一个矮个子的父母的主要内容,如果未能解决你的问题,请参考以下文章

角。使孩子 100% 宽度的 flex 父母

flex自适应超出省略

Flexbox 中的第一个孩子全角

css 怎样让div中的html标签向左浮动,因标签很多不像每个子标签都设左浮动?

当另一个孩子完成时如何退出一个子进程

使用 flex 将右框内容设置为右侧 [重复]