Flex 基础 100% 在列 flexbox 中:Firefox 中的全高,而不是 Chrome

Posted

技术标签:

【中文标题】Flex 基础 100% 在列 flexbox 中:Firefox 中的全高,而不是 Chrome【英文标题】:Flex basis 100% in column flexbox: full height in Firefox, not in Chrome 【发布时间】:2015-11-04 06:39:24 【问题描述】:

我想要一列任意数量的 div,每个 div 的宽度为父 div 的 100%,高度为 100%,所以一个最初是可见的,而其他的则向下溢出父级。我已将 div 设置为具有 flex: 0 0 100%;,在具有 display: flexflex-direction: column 的父 div 内实现此目的。

父 div 本身的高度未知,因此它也是 display: flexflex-direction: column 的子级,设置为 flex: 1 0 0 以占用其容器中的剩余空间。

在 Firefox 中,输出如我所愿:

但是,不是在 Chrome 中:

如何在没有 javascript 的情况下在 Chrome 中实现 Firefox 风格?

您可以在 http://plnkr.co/edit/WnAcmwAPnFaAhqqtwhLL?p=preview 上看到这一点,以及 flex-direction: row 的相应版本,它在 Firefox 和 Chrome 中都可以正常工作。

完整的 CSS 供参考

.wrapper 
  display: flex;
  flex-direction: column;
  height: 150px;
  width: 200px;
  border: 4px solid green;
  margin-bottom: 20px;


.column-parent 
  flex: 1 0 0;
  display: flex;
  flex-direction: column;
  border: 2px solid blue;


.column-child 
  flex: 0 0 100%;
  border: 2px solid red;

html

<div class="wrapper">
  <p>Some content of unknown size</p>
  <div class="column-parent">
    <div class="column-child">
      Should be inside green
    </div>
    <div class="column-child">
      Should be outside green
    </div>
  </div>
</div>

【问题讨论】:

请注意,在 Firefox 中 - 如果您添加额外的列子元素 - 它们会崩溃(就像在 Chrome 中一样)Plunker 我在我的回答中添加了另一个解决方案,不太老套 Chrome / Safari not filling 100% height of flex parent 【参考方案1】:

这似乎是 Chrome 的一个错误。与此处报告的 (issue 428049) 类似,可能与 (issue 346275) 有关。

This says:

- 浏览器应该解析弹性项目的孩子的百分比,*如果*它的弹性基础是确定的。 - Gecko *总是*解决百分比,无论弹性基础如何。 - Chrome *从不*解决百分比,无论弹性基础如何。

总而言之,Chrome 不会解析 flex-item 子项的百分比高度(即使子项本身是 flex-item),而所有其他浏览器都会这样做。

这可以在下面的 sn-p 中演示: (Fiddle here)

*  box-sizing: border-box; margin: 0; padding: 0; 
div.wrap 
    height: 120px; width: 240px; margin: 0px 12px;
    border: 1px solid blue; float: left;
    display: flex; flex-direction: column;    

div.parent 
    flex: 0 0 100%;
    border: 1px solid green; 
    display: flex; flex-direction: column;    

div.item 
    flex: 0 0 100%;
    border: 1px solid red;
<div class="wrap">
    <div class="item">a</div>
    <div class="item">b</div>
    <div class="item">c</div>
</div>
<div class="wrap">
    <div class="parent">
        <div class="item">a</div>
        <div class="item">b</div>
        <div class="item">c</div>
    </div>
</div>

第二个div 应该显示与第一个相同的行为。其他浏览器(IE11、Edge、FF39)正确显示。 Chrome 在这里失败并且不能正确解析div.item。它的父对象需要一个固定的高度,没有它它使用min-content 作为它的高度,因此不会溢出。

然而,在第一个 div 中,div.items 被正确解析并相应地溢出。这是因为父节点上有一个固定的高度(即div.wrap


可能的解决方案:

作为一种解决方法,如果您确定在包装器中只有两个元素pdiv),那么您可以给它们一个50% 高度。您必须向您的.column-parent 提供height:50%。如上所示,Chrome 需要在父级上固定高度。

然后一切都会按照您的需要进行。

演示小提琴:http://jsfiddle.net/abhitalks/kqncm65n/

相关 CSS

.wrapper > p  flex: 0 0 50%;   /* this can be on flex-basis */
.column-parent 
    flex: 1 0 auto; height: 50%; /* but, this needs to be fixed height */
    display: flex; flex-direction: column;
    border: 2px solid blue;

.column-child 
    flex: 0 0 100%;              /* this flex-basis is then enough */
    border: 2px solid red;

PS:jsfiddle 和 plnkr 的渲染方式似乎也存在差异。我不知道为什么,但有时我会得到不同的结果!

【讨论】:

HTML 在this fiddle 中正确输入。不打印值的原因是什么?【参考方案2】:

正如 Abhitalks 响应中所述,Chrome 在此处处理 height 属性的方式存在错误(或对标准的不同解释)。

我发现了一个在 Chrome FF 和 IE 中都可以使用的 hack

唯一的问题是您需要尽可能多地制定规则。

诀窍是将 flex-direction 设置为 row,将 flex-basis(即现在的宽度)设置为 100%,然后平移元素

.container 
    border: solid 2px blue;
    height: 200px;
    width: 200px;
    display: flex;
    flex-direction: column;
    position: relative;


.filler 
    border: solid 1px black;
    flex: 0 0 80px;
    background-color: lightgreen;
    transition: flex 1s;


.container:hover .filler 
    flex: 0 0 40px;


.test 
    border: solid 1px red;
    flex: 1 0 25px;
    display: flex;
    flex-direction: row;
    position: relative;


.child 
    background-color: rgba(200, 0, 0, 0.26);
    flex: 0 0 100%; 


.child:nth-child(2) 
    background-color: rgba(255, 255, 0, 0.48);
    transform: translateX(-100%) translateY(100%);


.child:nth-child(3) 
    background-color: rgba(173, 216, 230, 0.28);
    transform: translateX(-200%) translateY(200%);
<div class="container">
    <div class="filler"></div>
    <div class="filler"></div>
    <div class="test">
    	   <div class="child">1</div>
    	   <div class="child">2</div>
    	   <div class="child">3</div>
    </div>
</div>

如果可能有另一个孩子,则需要一个 nth-child(4) 规则,依此类推

我添加了一个悬停效果来检查大小如何适应

【讨论】:

我实际上倾向于您最初发布的解决方案...您可以在单独的答案中发布每个解决方案吗?我认为它们似乎完全不同,足以保证这一点。 嗨!我打算拆分答案,我看到你已经接受了它......现在我不知道该怎么办。如果您愿意,请随意编辑它:-) 我认为拆分它仍然会更好,因为它们是不同的解决方案。我怀疑我会将赏金奖励给你第一个发布的人。【参考方案3】:

我之前的回答是利用所需布局的特定设置的 hack。

解决此 Chrome 错误的另一种更通用的方法是在布局中使用中间元素,并使用 top: 0px 和 bottom: 0px 设置此元素大小。 (而不是高度:100%)Chrome 处理微积分的​​方式仍然存在一个错误,需要一个假动画才能使其正确调整

.container 
    border: solid 2px blue;
    height: 200px;
    width: 200px;
    display: flex;
    flex-direction: column;
    position: relative;


.filler 
    border: solid 1px black;
    flex: 0 0 94px;
    background-color: lightgreen;
    transition: 1s;


.container:hover .filler 
    flex: 0 0 50px;


.test 
    border: solid 1px red;
    flex: 1 0 25px;
    display: flex;
    flex-direction: row;
    position: relative;


@-webkit-keyframes adjust2 
    0% flex-basis: 100%;
  100% flex-basis: 100.1%;

.child 
    background-color: rgba(200, 0, 0, 0.26);
    width:  100%;
    height: 100%;
    flex: 1 0 100%;
    -webkit-animation: adjust2 1s infinite; /* only needed for webkit bug */


.intermediate 
    width:  100%;
    position: absolute;
    top: 0px;
    bottom: 0px;
    display: flex; 
    flex-direction: column; 


.child:nth-child(n+2) 
    background-color: rgba(255, 255, 0, 0.48);


.child:nth-child(n+3) 
    background-color: rgba(173, 216, 230, 0.28);
<div class="container">
    <div class="filler"></div>
    <div class="test">
        <div class="intermediate">
    	       <div class="child"></div>
    	       <div class="child"></div>
    	       <div class="child"></div>
        </div>
    </div>
</div>

【讨论】:

【参考方案4】:

向容器中添加 100% 怎​​么样:

.column-parent 
  flex: 1 0 100%;

并且在不调整flex基础的情况下,在包含的元素中flex-grow为1:

.column-child 
  flex: 1 0 0;

它的外观如下:http://plnkr.co/edit/H25NQxLtbi65oaltNVax?p=preview

【讨论】:

啊不完全...还有未知数量的子元素。如果有 3 个,则此技术无法达到我想要的效果:plnkr.co/edit/21KD5kuIw3yLKX2NL70l?p=preview。 你说得对。如果我们无法事先知道子元素的数量,那么这种替代方案就行不通。

以上是关于Flex 基础 100% 在列 flexbox 中:Firefox 中的全高,而不是 Chrome的主要内容,如果未能解决你的问题,请参考以下文章

Chrome 中的 Flexbox 容器没有达到 100% 的高度 [重复]

Flexbox:如何在列上组合百分比、像素和剩余高度?

Flexbox - 填充剩余空间[重复]

我怎样才能让 Flexbox 孩子 100% 的高度是他们的父母?

强制 flexbox 容器内的图像填充/覆盖 100%

flexbox 列子级的高度 100% [重复]