Html 嵌套的 flexboxes 跨浏览器的工作方式不同
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18639129/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Nested flexboxes works differently across browsers
提问by Thomas
I have a small example of a nested flexbox setup: http://jsfiddle.net/ThomasSpiessens/MUrPj/12/
我有一个嵌套 flexbox 设置的小例子:http: //jsfiddle.net/ThomasSpiessens/MUrPj/12/
In this example the following applies:
在本例中,以下适用:
- CSS 'box' classes use flexbox properties on which only the boxContent is told to grow. For specific CSS properties and values, please check the fiddle.
- 'fullSize' just sets both width and height to 100%.
- CSS 'box' 类使用 flexbox 属性,只有 boxContent 被告知在其上增长。对于特定的 CSS 属性和值,请查看 fiddle。
- 'fullSize' 只是将宽度和高度都设置为 100%。
When you check this fiddle with Firefox and Chrome you get different results. In Firefox it does what I would suppose it has to do, which is stretching the inner .boxContent. In Chrome however, the inner .boxContent doesn't get stretched.
当您使用 Firefox 和 Chrome 检查此小提琴时,您会得到不同的结果。在 Firefox 中,它会做我认为必须做的事情,即拉伸内部 .boxContent。然而,在 Chrome 中,内部 .boxContent 不会被拉伸。
Would anyone have an idea how to make the content stretch in Chrome as well ? perhaps a specific webkit property that is missing ?
有没有人知道如何在 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>
采纳答案by cimmanon
Unless you needthat extra div, remove it. There is sometimes a difference between the height of an element and its length along the main axis(column orientation), which is causing some confusion here. Basically, it lookslike it is taller than the browser believes it to be, which is why height: 100%
doesn't work like you expect (I'm not certain which behavior is correct in this instance).
除非您需要额外的 div,否则将其删除。有时,元素的高度与其沿主轴的长度(列方向)之间存在差异,这会在这里引起一些混淆。基本上,它看起来比浏览器认为的要高,这就是为什么height: 100%
不像您期望的那样工作(我不确定在这种情况下哪种行为是正确的)。
For whatever reason, promoting the element to a flex containerworks.
无论出于何种原因,将元素提升到flex 容器都有效。
<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>
回答by ldwg
This question has been linked for a specific problem: How to make nested elements in a flex box fill the whole height?The short answer is:
这个问题已被链接到一个特定的问题:如何使 flex 框中的嵌套元素填充整个高度?简短的回答是:
Use display:flex
on the child and avoid height:100%
. Here is a simplified example on codepen.
display:flex
对孩子使用并避免height:100%
。这是关于 codepen的简化示例。
CourtDemoneexplained it well (more here):
CourtDemone解释得很好(更多在这里):
According to the flexbox spec, an
align-self:stretch
value (the default for a flex'd element) changes only the usedvalue of an element's cross-size property (in this case, height). Percentages however are calculated from the specifiedvalue of the parent's cross-size property, not it's used value.
根据 flexbox 规范,一个
align-self:stretch
值(flex 元素的默认值)仅更改元素的 cross-size 属性(在本例中为高度)的使用值。然而,百分比是根据父项的跨尺寸属性的指定值计算的,而不是它的使用值。
回答by user3200478
I've found a solution without removing the extra-div.
我找到了一个无需删除额外 div 的解决方案。
You need to make boxContent relative positioned and its containing box absolute.
您需要使 boxContent 相对定位,并且它的包含框是绝对的。
With attaching an extra css class to the inner div:
将额外的 css 类附加到内部 div:
<div class="boxContent">
<div class="box fullSize innerBox">
and following css:
和以下CSS:
.boxContent {
...
position: relative;
}
.innerBox{
position: absolute;
top: 0px;
bottom: 0px;
}
here's the updated jsfiddle: http://jsfiddle.net/MUrPj/223/
这是更新的 jsfiddle:http: //jsfiddle.net/MUrPj/223/
This question is pretty old, but this might be helpful for future visitors
这个问题很老了,但这可能对未来的访问者有所帮助
回答by ToolmakerSteve
This JsFiddleis the minimum needed CSS attributes to get nested flexboxes to work. I've shown it for column; if you are doing this within a row, remove the two "flex-direction: column"s. [In this trivial example, removing those won't change anything, because there is only one child of each flexbox. But as soon as you add a second child, you'll be working in either a row or a column.]
这个 JsFiddle是让嵌套的 flexbox 工作所需的最少 CSS 属性。我已经为列展示了它;如果您在一行中执行此操作,请删除两个“flex-direction: column”。[在这个简单的例子中,删除那些不会改变任何东西,因为每个 flexbox 只有一个孩子。但是一旦您添加了第二个孩子,您将在一行或一列中工作。]
HTML:
HTML:
<div id="e1">
<div id="e2">
<div id="e3">
</div>
</div>
</div>
CSS:
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;
}
In my experience, Safari 13 (both MacOS and iOS) is more finicky (re nested flex items) than Chrome 77, Firefox 69, or even Edge 18.
While in this simpleexample, all 3 react the same, I had a more complex situation which worked in all but Safari. Nevertheless, the code shown here -- especially the two lines in #e2
after "Won't work if remove either of the next 2 lines" -- is the essence of what made my more complex situation work in Safari.
根据我的经验,Safari 13(MacOS 和 iOS)比 Chrome 77、Firefox 69 甚至 Edge 18 更挑剔(重新嵌套弹性项目)。
虽然在这个简单的例子中,所有 3 种反应相同,但我有一个更复杂的这种情况在除 Safari 之外的所有情况下都有效。尽管如此,此处显示的代码——尤其是#e2
“如果删除接下来的两行中的任何一行都将不起作用”之后的两行——是使我在 Safari 中运行更复杂情况的本质所在。
In addition, if having difficulties, first step is to remove all "percent" height attributeswithin the nested elements. Here, that means #e1
is permitted to have height: 100%
- this is within the context of itsparent, which is nota flex container. But #e2
and #e3
should notdeclare %
heights.
此外,如果遇到困难,第一步是删除嵌套元素中的所有“百分比”高度属性。在此,装置#e1
被允许有height: 100%
-这是的范围内它的母体,它是不柔性容器。但是,#e2
和#e3
应不申报%
的高度。
Having nested elements with heights that are not relative to their parent(pixels, ems, vh) are fine, AFAIK. Note that vh works, because it is relative to window size, which isn't affected by the nested flex containers' (#e1, #e2) heights. So that calculation logic is easy for browser to get right.
嵌套元素的高度与其父元素(像素,ems,vh)无关,AFAIK。请注意, vh 有效,因为它与窗口大小相关,不受嵌套 flex 容器的 (#e1, #e2) 高度的影响。这样计算逻辑很容易让浏览器正确。
As requested, example of nesting four deep. Uses class names to make it easier.
根据要求,嵌套四个深的示例。使用类名使其更容易。
HTML:
HTML:
<div class="fb-outer">
<div class="fb-middle">
<div class="fb-middle">
<div class="fb-inner">
</div>
</div>
</div>
</div>
CSS:
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;
}