Chrome / Safari无法填充100%高度的flex parent [英] Chrome / Safari not filling 100% height of flex parent
问题描述
我想要一个具有特定高度的垂直菜单。
每个孩子必须填充父节点的高度,并具有中间对齐的文本。
孩子的数量是随机的,所以我必须使用动态值。
Div 。 container
包含随机数的子元素( .item
),始终必须填充父元素的高度。为了实现我使用flexbox。
为了使链接文本与中间对齐,我使用 display:table-cell
技术。但是使用表格显示需要使用高度100%。
我的问题是 .item-inner {height:100%}
在webkit(Chrome)中不起作用。
- 这个问题有解决方法吗?
- 或者有不同的技术让所有
.item
填充父文本的高度,文本垂直对齐到中间?
此处的示例jsFiddle应该在Firefox和Chrome中查看
.container {height:20em;显示:flex; flex-direction:column; border:5px solid black} .item {flex:1; border-bottom:1px solid white;}。item-inner {height:100%; width:100%; display:table;} a {background:orange; display:table-cell; vertical-align:middle;}
< div class = container> < div class =item> < div class =item-inner> < a>按钮< / a> < / div> < / div> < div class =item> < div class =item-inner> < a>按钮< / a> < / div> < / div> < div class =item> < div class =item-inner> < a>按钮< / a> < / div> < / div>< / div>
问题
我的问题是
.item-inner {height:100% }
这不工作,因为你在
webkit
百分比
指定百分比高度。该百分比是相对于生成的框的
包含块的高度计算的。如果包含块的高度不是
明确指定,并且此元素不是绝对定位的,则该值计算为auto
。
自动
高度取决于其他属性的值。
换句话说,对于在流内子女上工作的百分比高度,父级必须具有设置的高度。
,顶层容器具有定义的高度: .container {height:20em; }
第三级容器具有定义的高度: .item-inner {height:100%; }
但是在它们之间,二级容器– .item
– 不具有定义的高度。 Webkit认为这是一个缺失的链接。
.item-inner
告诉Chrome: code> height:100% 。 Chrome会查找父项( .item
)以供参考,并回应: 100%的内容?我没有看到任何(忽略 flex:1
规则)。因此,它会根据规范应用 height:auto
(内容高度)。
<另一方面,现在接受父级的flex高度作为孩子的百分比高度的参考。 IE11和Edge也接受flex高度。
此外,Chrome会接受 flex-grow
引用如果与 flex-basis
(任何值都有效,包括 flex-basis:0
)。但是,在此写作中,此解决方案在Safari中失败。
#outer {display:flex; flex-direction:column; height:300px; background-color:white; border:1px solid red;}#middle {flex-grow:1; flex-basis:1px; background-color:yellow;}#inner {height:100%; background-color:lightgreen;}
< div id = outer> < div id =middle> < div id =inner> INNER< / div> < / div>< / div>
$ b b
解决方案
1。在所有父元素上指定高度
一个可靠的跨浏览器解决方案是在所有父元素上指定高度。
注意 min-height
和 max-height
是不可接受的。必须是 height
属性。
CSS相对和绝对定位
将位置:相对
应用于父级和 position:absolute
。
使用 height:100%
和设置绝对定位的子尺寸width:100% / code>,或使用偏移属性:
top:0
, right:0
, bottom:0
, left:0
。
百分比高度在父级上没有指定高度。
3。删除不需要的HTML容器(推荐)
按钮< c>?为什么不删除
.item
或 .item-inner
或两者?虽然 按钮
元素有时会作为弹性容器失败,但它们可以是flex项目。考虑使按钮为
.container
或 .item
-lang =jsdata-hide =truedata-console =truedata-babel =false>
.container {height:20em;显示:flex; flex-direction:column; border:5px solid black} a {flex:1;背景:橙色; border-bottom:1px solid white;显示:flex; / *嵌套flex容器(用于对齐文本)* / align-items:center; / *中心文本垂直* / justify-content:center; / * center text horizontally horizontal * /}
< div class =container> < a>按钮< / a> < a>按钮< / a> < a> Button< / a>< / div>
4。嵌套Flex容器(推荐)
删除百分比高度。除去表属性。除去 vertical-align
。避免绝对定位。
应用 display:flex
flex item( .item
),使其成为一个flex容器。这会自动设置 align-items:stretch
,它告诉孩子( .item-inner
)展开全高
.container {display:flex; flex-direction:column; height:20em; border:5px solid black} .item {display:flex; / * new;嵌套的flex容器* / flex:1; border-bottom:1px solid white;}。item-inner {display:flex; / * new;嵌套的flex容器* / flex:1; / * new * / / * height:100%; < - remove;不必要* / / * width:100%; < - remove;不必要* / / * display:table; < - remove;不必要* /} a {display:flex; / * new;嵌套的flex容器* / flex:1; / * new * / align-items:center; / * new;垂直中心文本* /背景:橙色; / * display:table -cell; < - remove;不必要* / / * vertical-align:middle; < - remove;不必要* /}
< div class = > < div class =item> < div class =item-inner> < a>按钮< / a> < / div> < / div> < div class =item> < div class =item-inner> < a>按钮< / a> < / div> < / div> < div class =item> < div class =item-inner> < a>按钮< / a> < / div> < / div>< / div>
jsFiddle
更多信息
如何在CSS中正常工作的百分比:
使用父级flex高度作为子级百分比高度参考的Firefox和IE示例: $ b I want to have a vertical menu with a specific height. Each child must fill the height of the parent and have middle-aligned text. The number of children is random, so I have to work with dynamic values. Div For making links with text aligned to the middle I am using My problem is that Example here jsFiddle, should be viewed in Firefox and Chrome
.container
contains a random number of children (.item
) that always have to fill the height of the parent. To achieve that I used flexbox. display: table-cell
technique. But using table displays requires using a height 100%..item-inner { height: 100% }
is not working in webkit (Chrome).
.item
fill the height of the parent with text vertical aligned to middle?.container {
height: 20em;
display: flex;
flex-direction: column;
border: 5px solid black
}
.item {
flex: 1;
border-bottom: 1px solid white;
}
.item-inner {
height: 100%;
width: 100%;
display: table;
}
a {
background: orange;
display: table-cell;
vertical-align: middle;
}
<div class="container">
<div class="item">
<div class="item-inner">
<a>Button</a>
</div>
</div>
<div class="item">
<div class="item-inner">
<a>Button</a>
</div>
</div>
<div class="item">
<div class="item-inner">
<a>Button</a>
</div>
</div>
</div>
The Problem
My problem is that
.item-inner { height: 100% }
is not working in webkit (Chrome).
It's not working because you're using percentage height in a way that doesn't conform with the traditional implementation of the spec.
10.5 Content height: the
height
propertypercentage
Specifies a percentage height. The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly and this element is not absolutely positioned, the value computes toauto
.auto
The height depends on the values of other properties.
In other words, for percentage height to work on an in-flow child, the parent must have a set height.
In your code, the top-level container has a defined height: .container { height: 20em; }
The third-level container has a defined height: .item-inner { height: 100%; }
But between them, the second-level container – .item
– does not have a defined height. Webkit sees that as a missing link.
.item-inner
is telling Chrome: give me height: 100%
. Chrome looks to the parent (.item
) for reference and responds: 100% of what? I don't see anything (ignoring the flex: 1
rule that is there). As a result, it applies height: auto
(content height), in accordance with the spec.
Firefox, on the other hand, now accepts a parent's flex height as a reference for the child's percentage height. IE11 and Edge accepts flex heights, as well.
Also, Chrome will accept flex-grow
as an adequate parent reference if used in conjunction with flex-basis
(any value works, including flex-basis: 0
). As of this writing, however, this solution fails in Safari.
#outer {
display: flex;
flex-direction: column;
height: 300px;
background-color: white;
border: 1px solid red;
}
#middle {
flex-grow: 1;
flex-basis: 1px;
background-color: yellow;
}
#inner {
height: 100%;
background-color: lightgreen;
}
<div id="outer">
<div id="middle">
<div id="inner">
INNER
</div>
</div>
</div>
Solutions
1. Specify a height on all parent elements
A reliable cross-browser solution is to specify a height on all parent elements. This prevents missing links, which Webkit-based browsers consider a violation of the spec.
Note that min-height
and max-height
are not acceptable. It must be the height
property.
2. CSS Relative & Absolute Positioning
Apply position: relative
to the parent and position: absolute
to the child.
Size the absolutely positioned child with height: 100%
and width: 100%
, or use the offset properties: top: 0
, right: 0
, bottom: 0
, left: 0
.
With absolute positioning, percentage height works without a specified height on the parent.
3. Remove unnecessary HTML containers (Recommended)
Is there a need for two containers around button
? Why not remove .item
or .item-inner
, or both? Although button
elements sometimes fail as flex containers, they can be flex items. Consider making button
a child of .container
or .item
, and removing gratuitous mark-up.
Here's an example:
.container {
height: 20em;
display: flex;
flex-direction: column;
border: 5px solid black
}
a {
flex: 1;
background: orange;
border-bottom: 1px solid white;
display: flex; /* nested flex container (for aligning text) */
align-items: center; /* center text vertically */
justify-content: center; /* center text horizontally */
}
<div class="container">
<a>Button</a>
<a>Button</a>
<a>Button</a>
</div>
4. Nested Flex Containers (Recommended)
Get rid of percentage heights. Get rid of table properties. Get rid of vertical-align
. Avoid absolute positioning. Just stick with flexbox all the way through.
Apply display: flex
to the flex item (.item
), making it a flex container. This automatically sets align-items: stretch
, which tells the child (.item-inner
) to expand the full height of the parent.
Try this (no changes to HTML):
.container {
display: flex;
flex-direction: column;
height: 20em;
border: 5px solid black
}
.item {
display: flex; /* new; nested flex container */
flex: 1;
border-bottom: 1px solid white;
}
.item-inner {
display: flex; /* new; nested flex container */
flex: 1; /* new */
/* height: 100%; <-- remove; unnecessary */
/* width: 100%; <-- remove; unnecessary */
/* display: table; <-- remove; unnecessary */
}
a {
display: flex; /* new; nested flex container */
flex: 1; /* new */
align-items: center; /* new; vertically center text */
background: orange;
/* display: table-cell; <-- remove; unnecessary */
/* vertical-align: middle; <-- remove; unnecessary */
}
<div class="container">
<div class="item">
<div class="item-inner">
<a>Button</a>
</div>
</div>
<div class="item">
<div class="item-inner">
<a>Button</a>
</div>
</div>
<div class="item">
<div class="item-inner">
<a>Button</a>
</div>
</div>
</div>
jsFiddle
More Information
How percentage heights normally work in CSS:
Examples of Firefox and IE using a parent's flex height as reference for a child's percentage height:
- Chrome ignoring flex-basis in column layout
- Height is not correct in flexbox items in Chrome
- Flexbox in Chrome--How to limit size of nested elements?
- min-height inside a flex item is being ignored in chrome
这篇关于Chrome / Safari无法填充100%高度的flex parent的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!