嵌套的弹性盒在浏览器中的工作方式不同
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; . 您可以通过提供有关您提出的解决方案的一些见解来改进您的答案。以上是关于嵌套的弹性盒在浏览器中的工作方式不同的主要内容,如果未能解决你的问题,请参考以下文章