嵌套的弹性盒在浏览器中的工作方式不同

Posted

技术标签:

【中文标题】嵌套的弹性盒在浏览器中的工作方式不同【英文标题】:Nested flexboxes works differently across browsers 【发布时间】:2013-09-09 10:52:46 【问题描述】:

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

在此示例中适用以下内容:

CSS 'box' 类使用 flexbox 属性,只有 boxContent 被告知增长。对于特定的 CSS 属性和值,请检查小提琴。 '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>

【问题讨论】:

【参考方案1】:

除非你需要那个额外的 div,否则删除它。有时元素的高度与其沿主轴(列方向)的长度之间存在差异,这在此处引起了一些混乱。基本上,它 看起来 比浏览器认为的要高,这就是为什么 height: 100% 不能像您预期的那样工作(我不确定在这种情况下哪种行为是正确的) .

无论出于何种原因,将元素提升为 flex 容器 都可以。

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>

【讨论】:

这对我有用。在任何情况下都无法让包装器 div 伸展。摆脱它并且工作正常。有点烦人。 太棒了!这是一个救生员。 :)【参考方案2】:

我找到了一个不删除额外 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/

这个问题已经很老了,但这可能对未来的访问者有所帮助

【讨论】:

谢谢人,在我的情况下最好的解决方案,嵌套元素必须是内联块【参考方案3】:

这个问题已经链接到一个特定的问题:如何让弹性盒子中的嵌套元素填满整个高度?简短的回答是:

对孩子使用display:flex,避免使用height:100%。这是simplified example on codepen。

CourtDemone解释得很好(更多here):

根据 flexbox 规范,align-self:stretch 值(flex 元素的默认值)仅更改元素的 cross-size 属性(在本例中为高度)的 used 值.然而,百分比是根据父级的 cross-size 属性的指定值计算的,而不是它的使用值。

【讨论】:

它对我有用,div 容器(flex)有行,行有两个元素/单元格。第一个元素是固定宽度,第二个是填充剩余的宽度。 display:flex 在行上做了魔术。【参考方案4】:

This JsFiddle 是让嵌套的弹性框工作所需的最低 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)比 Chrome 77、Firefox 69 甚至 Edge 18 更挑剔(重新嵌套弹性项目)。 虽然在 这个简单的 示例中,所有 3 个反应都相同,但我有一个更复杂的情况,它在除 Safari 之外的所有情况下都有效。尽管如此,这里显示的代码——尤其是#e2 中“如果删除接下来的 2 行中的任何一个将不起作用”之后的两行——是使我在 Safari 中工作的更复杂情况的本质。

此外,如果遇到困难,第一步是删除嵌套元素中的所有“百分比”高度属性。在这里,这意味着#e1 被允许拥有height: 100% - 这是在 父级的上下文中,它不是 一个弹性容器。但是#e2#e3 应该声明% 高度。

拥有 高度与其父级无关(像素、ems、vh)的嵌套元素很好,AFAIK。请注意 vh 有效,因为它与窗口大小有关,不受嵌套弹性容器(#e1,#e2)高度的影响。这样计算逻辑很容易让浏览器搞对。


根据要求,example of nesting four deep。使用类名使其更容易。

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 的子级)? 是的,您可以随心所欲地深入。使所有“中间”级别的 css 与 e2 相同。为了使这更容易,请使用“类名”而不是“ids”。不知道为什么我使用ID。我将编辑答案以显示。 谢谢!使用该示例,我发现在使用 Angular 组件时,必须将宿主元素视为另一个 fb-middle 才能使其正常工作。【参考方案5】:

*,*::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 来修复它,你在嵌套容器 class="box fullSize" 到 class="box" 上使用了第二个时间并给定了 body width:100%;高度:100vh;。注意:高度:100vh;对于一个身体来说真的很重要。实际上浏览器覆盖了 .boxContent -ms-flex: 1 0 auto;-webkit-flex: 1 0 auto;flex: 1 0 auto;-webkit-box-flex: 1.0;background-color: yellow; === = WITH === .fullSize 宽度:100%;高度:100%;边距:0;填充:0; . 您可以通过提供有关您提出的解决方案的一些见解来改进您的答案。

以上是关于嵌套的弹性盒在浏览器中的工作方式不同的主要内容,如果未能解决你的问题,请参考以下文章

为什么navigator.mediaDevices在本地主机和服务器中的工作方式不同?

弹性盒子

可见性:隐藏在不同浏览器上的工作方式不同

Sencha Touch 2:在选项卡面板中创建嵌套列表

main 方法在枚举和类中的工作方式是不是不同?

为啥在数组中的值的情况下比较的工作方式不同