百分比高度:Chrome/Safari vs Firefox/IE
Chrome/Safari 中的 flex 项目无法识别其百分比高度的原因是 Webkit 浏览器坚持对规范的更传统解释:
<块引用>CSS height
属性
百分比
指定百分比高度.该百分比是根据生成的框的包含块的高度计算的.如果未明确指定包含块的高度并且此元素不是绝对定位,则该值计算为 auto
.
auto
高度取决于其他属性的值.
换句话说,如果您希望元素具有百分比高度,那么您必须指定父元素的高度.
这种语言的传统解释是高度"表示height
属性的值.尽管从语言中不清楚高度"的确切含义,但 height
属性要求一直是主要的实现.在处理百分比值时,我从未见过 min-height
、max-height
或其他形式的高度对父级起作用.
然而,正如本问题中所述(以及另一个和另一个和另一个)、Firefox(和 IE),显然)已经扩大了其解释以接受 flex
高度,以及.
目前尚不清楚哪个浏览器更符合标准.
height
定义自 1998 年以来没有更新,这无济于事 (CSS2).
总之,Chrome 和 Safari 会根据父级 height
属性的值解析百分比高度.Firefox 和 IE11/Edge 使用父计算的 flex 高度.
目前,在我看来,解决这个问题的最简单的跨浏览器解决方案是使用 height
属性来表示高度百分比.
更新:这里有更多解决方案:Chrome/Safari 未填充 100% 的 flex 父级高度
莉>I'm having trouble getting Chrome to pay attention to the flex-basis part of flex: 1 1 25%
in a flex-direction: column
layout. It works fine in a row
layout.
The snippet below demonstrates the problem: the yellow, blue, and pink bars are flex-basis 50px, 25%, and 75%, shown in both column and row flex directions.
If you run it in Firefox (or IE11 or Edge) both column and row divide up the area as expected:
But if you run it in Chrome (47) or Safari (9.0.3), the column layout on the left seems to ignore the flex-basis entirely -- the heights of the bars seem to have no relation to the flex-basis:
The only difference between left and right is the flex-direction
.
.container {
width: 400px;
height: 200px;
display: flex;
background: #666;
position: relative;
}
.layout {
flex: 1 1 100%; /* within .container */
margin: 10px;
display: flex;
}
.row {
flex-direction: row;
}
.column {
flex-direction: column;
}
.exact {
flex: 1 1 50px;
background: #ffc;
}
.small {
flex: 1 1 25%;
background: #cff;
}
.large {
flex: 1 1 75%;
background: #fcf;
}
<div class="container">
<div class="layout column">
<div class="exact">50px</div>
<div class="small">25%</div>
<div class="large">75%</div>
</div>
<div class="layout row">
<div class="exact">50px</div>
<div class="small">25%</div>
<div class="large">75%</div>
</div>
</div>
I tried adding height: 100%
to .column
, which makes Chrome pay attention to the flex-basis, but causes a different problem -- the flex gets bigger than its container:
.column {
flex-direction: column;
height: 100%;
}
I gather this is a long-standing webkit bug. Is there any way to work around it? (I'm trying to create some generalized layout components, so hard-coding specific numbers of children or specific pixel heights isn't workable.)
[EDIT] Here's an additional example showing the general problem (and avoiding the margin and total-greater-than-100% issues in the example above):
.container {
width: 300px;
height: 300px;
display: flex;
}
.layout {
flex: 1 1 100%; /* within its flex parent */
display: flex;
background: #ffc;
}
.row {
flex-direction: row;
}
.column {
flex-direction: column;
height: 100%; /* attempted workaround for webkit */
}
.small {
flex: 1 1 30%;
background: #cff;
}
.large {
flex: 1 1 70%;
background: #fcf;
}
div {
/* border/padding just makes divs easier to see --
you can remove all of this without changing the problem */
box-sizing: border-box;
border: 1px solid #999;
padding: 10px;
}
<div class="container">
<div class="layout row">
<div class="small">row: 30%</div>
<div class="large layout column">
<div class="small">row: 70%; col: 30%</div>
<div class="large">row: 70%; col: 70%</div>
</div>
</div>
</div>
解决方案
Three items to consider:
Sum of all heights greater than 100%
In your .column
layout, you have three flex items. Their heights are 75% + 25% + 50px
. This by itself exceeds the height: 100%
you applied. This does not cause an overflow because you have flex-shrink
set to 1
.
Margin space
You have specified margin: 10px
for both layouts. So there's an extra 20px of height from the top and bottom margins. In the .column
layout, this does indeed cause an overflow on Chrome.
Adjust for those extra 20px, and the overflow is gone:
.column {
flex-direction: column;
height: calc(100% - 20px); /* new */
}
.container {
width: 400px;
height: 200px;
display: flex;
background: #666;
position: relative;
}
.layout {
flex: 1 1 100%; /* within .container */
margin: 10px;
display: flex;
}
.row {
flex-direction: row;
}
.column {
flex-direction: column;
height: calc(100% - 20px); /* NEW */
}
.exact {
flex: 1 1 50px;
background: #ffc;
}
.small {
flex: 1 1 25%;
background: #cff;
}
.large {
flex: 1 1 75%;
background: #fcf;
}
<div class="container">
<div class="layout column">
<div class="exact">50px</div>
<div class="small">25%</div>
<div class="large">75%</div>
</div>
<div class="layout row">
<div class="exact">50px</div>
<div class="small">25%</div>
<div class="large">75%</div>
</div>
</div>
Percentage Heights: Chrome / Safari vs Firefox / IE
The reason the flex items in Chrome / Safari don't recognize their percentage heights is because Webkit browsers are adhering to a more traditional interpretation of the spec:
CSS height
property
percentage
Specifies a percentage height. The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly and this element is not absolutely positioned, the value computes to auto
.
auto
The height depends on the values of other properties.
In other words, if you want an element to have a percentage height, then you must specify a height on the parent.
The traditional interpretation of this language is that "height" means the value of the height
property. Although it's unclear from the language exactly what "height" means, the height
property requirement has been the predominant implementation. I've never seen min-height
, max-height
or other forms of height work on a parent when dealing with percentage values.
Recently, however, as noted in this question (and another one and another one and another one), Firefox (and IE, apparently) has broadened its interpretation to accept flex
heights, as well.
It's not clear which browser is more compliant with the standard.
It doesn't help matters that the height
definition hasn't been updated since 1998 (CSS2).
Bottom line, Chrome and Safari resolve percentage heights based on the value of the parent's height
property. Firefox and IE11/Edge use the parent's computed flex height.
For now, the simplest cross-browser solution to this problem would be, in my view, using the height
property across the board for percentage heights.
UPDATE: More solutions here: Chrome / Safari not filling 100% height of flex parent
这篇关于Chrome 忽略列布局中的 flex-basis的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文