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: flex
和 flex-direction: column
的父 div 内实现此目的。
父 div 本身的高度未知,因此它也是 display: flex
和 flex-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.item
s 被正确解析并相应地溢出。这是因为父节点上有一个固定的高度(即div.wrap
)
可能的解决方案:
作为一种解决方法,如果您确定在包装器中只有两个元素(p
和div
),那么您可以给它们一个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% 的高度 [重复]