问题描述
我想要一列 div,其中任何一个数字,每个 div 的宽度为 100%,高度为父 div 的 100%,因此最初可见 div,而其他 div 则超出父级。我已经将 div 设置为 flex: 0 0 100%;
,在 display: flex
和 flex-direction: column
的父 div 内实现。
父 div 本身身高不变,因此它也是 display: flex
和 flex-direction: column
的孩子,设置为 flex: 1 0 0
以在其容器中占用剩余空间。
在 Firefox 中,输出是我想要的:
但是,不在 Chrome 中:
如何在 Chrome 中实现 Firefox 风格,无需 Javascript?
您可以在 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>
最佳解决思路
正如 Abhitalks 的回应所述,Chrome 在这里处理高度属性的方式有一个错误 (或标准的不同解释) 。
我发现一个在 Chrome FF 和 IE 工作的黑客
唯一的问题是,你已经拥有与可口可乐的孩子一样多的规则。
诀窍是将 flex-direction 设置为行,将 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) 规则,等等
我添加了悬停效果来检查尺寸是如何适应的
次佳解决思路
这似乎是 Chrome 的错误。类似于这里报道的 (issue 428049),也许与 (issue 346275)有关。
- Browsers are supposed to resolve percentages on the flex item's child, *if* its flex-basis is definite. - Gecko is *always* resolving percentages regardless of the flex-basis. - Chrome is *never* resolving percentages, regardless of the flex-basis.
简而言之,Chrome 不能解决 flex-item 的孩子的百分比高度 (即使孩子本身是 flex-item),而所有其他浏览器都是这样。
这可以在下面的代码片段中展示:(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
被正确解析并相应溢出。这是因为在父母 (即 div.wrap
) 上有一个固定的高度
可能的解决方案:
作为解决方法,如果您确定在包装器中只有两个元素 (p
和 div
),那么您可以给他们一个 50%
高度。您必须提供 height:50%
.column-parent
。如上所述,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 渲染的方式似乎也有差异。我不知道为什么,但有时我得到不同的结果!
第三种解决思路
我以前的答案是一个利用所需布局的特定设置的黑客。
一般来说,解决这个 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>
第四种思路
如何将 100%添加到容器中?
.column-parent {
flex: 1 0 100%;
}
并将 flex-grow 置于 1 含量元素中,无需调整柔性基础:
.column-child {
flex: 1 0 0;
}
以下是它的外观:http://plnkr.co/edit/H25NQxLtbi65oaltNVax?p=preview
参考文献
注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。