嵌套的Flexbox在不同浏览器中表现不同

28

我有一个嵌套的flexbox设置小例子: http://jsfiddle.net/ThomasSpiessens/MUrPj/12/

在这个例子中,应用了以下规则:

  • CSS 'box'类使用flexbox属性,其中只告诉boxContent要增长。有关特定的CSS属性和值,请检查fiddle。
  • 'fullSize'只需将宽度和高度都设置为100%。

当您使用Firefox和Chrome检查此代码时,会得到不同的结果。 在Firefox中,它做的是我认为它应该做的事情,即拉伸内部的.boxContent。 然而,在Chrome中,内部的.boxContent并没有被拉伸。

是否有人有办法使内容在Chrome中也能自动拉伸?或许是缺少一些特定的webkit属性?

.fullSize {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

.box {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-box-orient: vertical;
  -moz-box-orient: vertical;
  -ms-flex-direction: column;
  -webkit-flex-direction: column;
  flex-direction: column;
  background-color: brown;
}


/* line 7, ../../app/styles/_layout.scss */

.boxHeader {
  -ms-flex: 0 0 auto;
  -webkit-flex: 0 0 auto;
  flex: 0 0 auto;
  background-color: green;
}


/* line 12, ../../app/styles/_layout.scss */

.boxContent {
  -ms-flex: 1 0 auto;
  -webkit-flex: 1 0 auto;
  flex: 1 0 auto;
  -webkit-box-flex: 1.0;
  background-color: yellow;
}


/* line 18, ../../app/styles/_layout.scss */

.boxFooter {
  -ms-flex: 0 1 auto;
  -webkit-flex: 0 1 auto;
  flex: 0 1 auto;
  background-color: cornflowerblue;
}

.moreblue {
  background-color: blue;
}

.moregreen {
  background-color: darkgreen;
}

.red {
  background-color: red;
}
<div class="box fullSize">
  <div class="boxHeader">HEADER</div>
  <div class="boxContent">
    <div class="box fullSize">
      <div class="boxHeader moregreen">INNER HEADER</div>
      <div class="boxContent red">CONTENT CONTENT CONTENT</div>
      <div class="boxFooter moreblue">INNER FOOTER</div>
    </div>
  </div>
  <div class="boxFooter">FOOTER</div>
</div>

5个回答

22

如果你不需要那个额外的

,就把它移除掉。有时元素的高度和它沿着主轴(列方向)的长度之间会有所区别,这会导致一些混淆。基本上,它看起来比浏览器认为的更高,这就是为什么height: 100%不能按照你的期望工作的原因(我不确定在这种情况下哪种行为是正确的)。

出于某种原因,把该元素提升为一个弹性容器就可以解决问题。

http://jsfiddle.net/MUrPj/14/

<div class="box fullSize">
    <div class="boxHeader">HEADER</div>
    <div class="boxContent box">
        <div class="boxHeader moregreen">INNER HEADER</div>
        <div class="boxContent red">CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT</div>
        <div class="boxFooter moreblue">INNER FOOTER</div>
    </div>
    <div class="boxFooter">FOOTER</div>
</div>

2
这对我有用。无论如何都无法使包装器div拉伸。把它去掉就可以了,工作得很好。有点烦人。 - Obie
太好了!这真是救命稻草。 :) - Dominus.Vobiscum

14

这个问题是针对一个具体问题而链接的:如何使嵌套在弹性盒子中的元素填满整个高度? 简短的答案是:

在子元素上使用display:flex,避免使用height:100%。以下是CodePen上的简化示例

CourtDemone解释得很好(更多信息请点击这里):

  

根据 flexbox 规范,align-self:stretch值(弹性元素的默认值)仅更改元素交叉轴属性(在这种情况下是高度)的used值。然而,百分比是从父元素交叉轴属性的指定值计算的,而不是其使用的值。


它对我起作用了,div容器(flex)有行,行有两个元素/单元格。第一个元素是固定宽度,第二个元素应填充剩余的宽度。在行上使用display:flex就可以实现这个效果。 - DavChana

4

我找到了一种解决方案,不需要删除额外的div。

您需要使boxContent相对定位,并使其包含盒子绝对定位。

通过附加一个额外的css类到内部div:

<div class="boxContent">
    <div class="box fullSize innerBox">

并且以下是css:

.boxContent {
  ...
    position: relative;
}
.innerBox{
    position: absolute;
    top: 0px;
    bottom: 0px;
}

以下是更新后的jsfiddle链接:http://jsfiddle.net/MUrPj/223/

虽然这个问题比较老,但对于未来的访问者可能会有所帮助。


谢谢,这是我情况下最好的解决方案,其中嵌套元素必须是 inline-blocks。 - Codeartist

2
这个JsFiddle展示了实现嵌套flexboxes所需的最小CSS属性。我展示了它在column中的使用;如果你在row中使用,移除两个"flex-direction: column"。[在这个简单的例子中,移除这些不会有任何改变,因为每个flexbox只有一个子元素。但是一旦你添加了第二个子元素,你就会在行或列中工作。]
HTML:
<div id="e1">
  <div id="e2">
    <div id="e3">    
    </div>
  </div>
</div>

CSS:

html, body, #e1 {
  height: 100%; width: 100%;
}
#e1 {
  background-color: #ff0000;
  display: flex;
  flex-direction: column;
}
#e2 {
  background-color: #ffff00;
  /* Won't work if remove either of the next 2 lines - a box collapses. */
  flex: 1;
  display: flex;
  flex-direction: column;
}
#e3 {
  background-color: #00ff00;
  flex: 1;
}

根据我的经验,Safari 13(包括MacOS和iOS)在处理嵌套的flex项目时比Chrome 77、Firefox 69甚至Edge 18更为挑剔。虽然在这个简单的例子中,所有三个浏览器的表现都一样,但我曾遇到过一个更复杂的情况,在这种情况下,除了Safari外,其他浏览器都能正常工作。尽管如此,这里展示的代码--特别是在“删除下面两行代码之一将无法工作”的#e2后面的两行代码--是使我在Safari中解决更复杂情况的关键。
另外,如果遇到困难,第一步是删除所有嵌套元素中的“百分比”高度属性。在这里,这意味着#e1可以具有height: 100%--这是在父级的上下文中,而该父级不是一个flex容器。但是,#e2#e3不应声明%高度。
具有与其父级不相关的高度(像素、ems、vh)的嵌套元素是可以接受的,据我所知。请注意,vh可以使用,因为它是相对于窗口大小的,而窗口大小不受嵌套flex容器(#e1、#e2)的高度影响。因此,浏览器很容易正确计算逻辑。
如请求所示,这是一个四级嵌套的示例。使用类名使其更容易理解。
HTML:
<div class="fb-outer">
  <div class="fb-middle">
    <div class="fb-middle">
      <div class="fb-inner">    
      </div>
    </div>
  </div>
</div>

CSS(层叠样式表):
html, body, .fb-outer {
  height: 100%; width: 100%;
}
.fb-outer {
  background-color: #ff0000;
  display: flex;
  flex-direction: column;
}
.fb-middle {
  background-color: #ffff00;
  /* Won't work if remove either of the next 2 lines. */
  flex: 1;
  display: flex;
  flex-direction: column;
}
.fb-inner {
  background-color: #00ff00;
  flex: 1;
}

有没有办法在那个层次结构中再添加一层嵌套(将“e4”作为“e3”的子元素添加)? - sawprogramming
1
是的,你可以深入到任何你想要的程度。将所有“中间”级别设置为与e2相同的CSS。为了使这更容易,使用“类名”而不是“ID”。不确定为什么要使用ID。我会编辑答案以显示。 - ToolmakerSteve
1
谢谢!使用这个例子,我发现在使用Angular组件时,主机元素必须被视为另一个fb-middle才能使其工作。 - sawprogramming

0

*,*::before,*::after {
margin:0;
padding:0;
box-sizing:border-box;

}
body {
width:100%;
height:100vh;
background-color:purple;
}

.fullSize {
   width: 100%;
   height: 100%; 
    margin: 0;
    padding: 0;
 
}



.box {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-box-orient: vertical;
  -moz-box-orient: vertical;
  -ms-flex-direction: column;
  -webkit-flex-direction: column;
  flex-direction: column;
  background-color: brown;
}

/* line 7, ../../app/styles/_layout.scss */
.boxHeader {
background-color: green;
}

/* line 12, ../../app/styles/_layout.scss */
.boxContent {
  -ms-flex: 1 0 auto;
  -webkit-flex: 1 0 auto;
  flex: 1 0 auto;
  -webkit-box-flex: 1.0;
  background-color: yellow;
}

/* line 18, ../../app/styles/_layout.scss */
.boxFooter {
  background-color: cornflowerblue;
}

.moreblue {
    background-color: blue;
}

.moregreen {
    background-color: darkgreen;
}

.red {
    background-color: red;
}
<div class="box fullSize">
    <div class="boxHeader">HEADER</div>
    <div class="boxContent">
            <div class="box">
                <div class="boxHeader moregreen">INNER HEADER</div>
                <div class="boxContent red">
                     CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT  
                </div>
                <div class="boxFooter moreblue">INNER FOOTER</div>
            </div>
        </div>
    <div class="boxFooter">FOOTER</div>
</div>


我通过删除一个无用的类名fullSize,该类名在嵌套容器类"box fullSize"上第二次使用,并将它改为"class =“box”" ,并给body {width:100%; height:100vh;}赋值从而解决了问题。注意:对于body来说,height:100vh;真的很重要。实际上,浏览器会覆盖.boxContent { -ms -灵活:1 0自动;-webkit -flex:1 0自动; flex:1 0自动; -webkit-box-flex:1.0; 背景颜色:黄色;} === =与===.fullSize {width:100%; height:100%; margin:0; padding:0;}。 - designcoded
你可以提供一些关于你所提出解决方案的见解,从而改进你的答案。 - Sanip

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接