Chrome 中 flexbox 项目的高度不正确

Height is not correct in flexbox items in Chrome

我有一个棘手的问题要问 CSS 大师。 我的果岭div有弹性高度,占了剩下的。 现在我想在 div 里面放一个 div ,它应该是绿色 div 的一半。但似乎 if Chrome 将其视为整个页面的一半而不是 flex 项目。

http://jsfiddle.net/unh5rw9t/1/

HTML

<body>
    <div id="wrapper">
        <div id="menu">
            1
        </div>
        <div id="content">2
            <div id="half_of_content">2.1</div>
        </div>
        <div id="footer" style="">
            3
        </div>
    </div>
</body>

CSS

html,body {
    height: 100%;
    margin: 0;
}

#wrapper {
    display: flex;
  flex-flow: column;
    height: 100%;
}

#menu {
    height: 70px; 
    background-color: purple
}

#content {
    flex: 1;
    height: 100%;
    background-color: green;
}

#half_of_content {
    height: 50%;
    background-color: yellow;
}

#footer {
    height: 100px; 
    background-color: cyan
}

@Michael_B 为什么 Chrome 会这样:

You gave the body a height: 100%. Then gave its child (.wrapper) a height: 100%. Then gave its child (.content) a height: 100%. So they're all equal height. Giving the next child (#half_of_content) a height: 50% would naturally be a 50% height of body.

但是Firefox不同意,因为实际上.contentheight: 100%被忽略了,它的高度是根据flex: 1.

计算的

即Chrome解析相对于父height属性值的百分比。 Firefox 会根据父项的已解析灵活高度来执行此操作。

正确的行为是 Firefox 的行为。根据Definite and Indefinite Sizes,

If a percentage is going to be resolved against a flex item’s main size, and the flex item has a definite flex basis, and the flex container has a definite main size, the flex item’s main size must be treated as definite for the purpose of resolving the percentage, and the percentage must resolve against the flexed main size of the flex item (that is, after the layout algorithm below has been completed for the flex item’s flex container, and the flex item has acquired its final size).

这是 Chrome 的解决方法:

#content {
  display: flex;
  flex-direction: column;
}
#content::after {
  content: '';
  flex: 1;
}
#half_of_content {
  flex: 1;
  height: auto;
}

这样 #content 中可用的 space 将平均分配给 #half_of_content::after 伪元素。

假设 #content 没有其他内容,#half_of_content 将是 50%。在你的例子中你有一个 2 在那里,所以它会比 50%.

少一点

html,
body {
  height: 100%;
  margin: 0;
}
#wrapper {
  display: flex;
  flex-flow: column;
  height: 100%;
}
#menu {
  height: 70px;
  background-color: purple
}
#content {
  flex: 1;
  height: 100%;
  background-color: green;
  display: flex;
  flex-direction: column;
}
#content::after {
  content: '';
  flex: 1;
}
#half_of_content {
  flex: 1;
  background-color: yellow;
}
#footer {
  height: 100px;
  background-color: cyan
}
<div id="wrapper">
  <div id="menu">
    1
  </div>
  <div id="content">2
    <div id="half_of_content">2.1</div>
  </div>
  <div id="footer" style="">
    3
  </div>
</div>

你绝对可以定位 div id="half_of_content".

#content {
    flex: 1;
    height: 100%;
    background-color: green;
    position: relative; /* new */
}

#half_of_content {
    height: 50%;
    background-color: yellow;
    position: absolute; /* new */
    width: 100%; /* new */
}

DEMO

关于你的陈述:

But it seems like if Chrome treats it like half of the whole page rather than the flex item.

你给了body一个height: 100%。然后给它child(.wrapper)一个height: 100%。然后给它child(.content)一个height: 100%所以它们都是等高的。给下一个child(#half_of_content)一个height: 50%自然是[=12=的50%高度].

然而,使用绝对定位,you don't need to specify parent heights

嵌套 flexboxes 有点问题。我通过添加带有 display: flex; 的内部包装器稍微修改了您的标记,这似乎可以完成这项工作。这是 fiddle(也使用 class 名称而不是 ID)。

<div class="content">
  <div class="wrapper-inner">
    2
    <div class="half">
      2.1
    </div>
  </div>
</div>

.wrapper-inner {
    position: absolute;
    display: flex;
    flex-direction: column;
    height: 100%;
    width: 100%;
}

修复:

#content 上设置

display: flex; 
flex-flow: column nowrap; 
justify-content: flex-end

#half_of_content 上设置 flex: 0 0 50%

警告:您需要添加 extra div 作为 #content 的子项。

完整示例如下:

html,body {
    height: 100%;
    margin: 0;
}

#wrapper {
    display: flex;
  flex-flow: column;
    height: 100%;
}

#menu {
    height: 70px; 
    background-color: purple
}

#content {
    flex: 1;
    height: 100%;
    display:flex;
    flex-flow: column nowrap;
    justify-content: flex-end;
    background-color: green;
}

#half_of_content {
    flex: 0 0 50%;
    background-color: yellow;
}

#footer {
    height: 100px; 
    background-color: cyan
}
<body>
    <div id="wrapper">
        <div id="menu">
            1
        </div>
        <div id="content">2
            <div id="half_of_content">2.1</div>
        </div>
        <div id="footer" style="">
            3
        </div>
    </div>
</body>