Solution
使用嵌套的弹性容器。
摆脱百分比高度。摆脱表属性。摆脱vertical-align
。避免绝对定位。一直坚持使用 Flexbox 就可以了。
Apply display: flex
到弹性项目(.item
),使其成为一个弹性容器。这会自动设置align-items: stretch
,它告诉孩子(.item-inner
) 以扩展父级的完整高度。
重要提示:要使此方法起作用,请从弹性项目中删除指定的高度。如果孩子有指定的身高(例如height: 100%
),那么它将忽略align-items: stretch
来自父母。为了stretch
默认工作,孩子的身高必须计算为auto
(完整解释 https://stackoverflow.com/q/44878379/3597276).
试试这个(不改变 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 演示 http://jsfiddle.net/y8mboo2s/3/
解释
我的问题是.item-inner { height: 100% }
不在工作
webkit(Chrome)。
它不起作用,因为您使用百分比高度的方式不符合规范的传统实现。
10.5 内容高度:height财产 http://www.w3.org/TR/CSS22/visudet.html#the-height-property
百分比
指定百分比高度。百分比是根据生成的框的高度计算的
包含块。如果包含块的高度不是
明确指定并且该元素不是绝对定位的,该值计算为auto
.
auto
高度取决于其他属性的值。
换句话说,要使百分比高度适用于流入孩子,父母must有一个设定的高度。
在您的代码中,顶级容器具有定义的高度:.container { height: 20em; }
第三层容器有一个定义的高度:.item-inner { height: 100%; }
但在它们之间,还有第二层容器——.item
– does not有规定的高度。 Webkit 认为这是一个缺失的环节。
.item-inner
正在告诉 Chrome:give me height: 100%
。 Chrome 会向父级 (.item
)供参考并回应:100% 什么?我什么也没看到(忽略flex: 1
那里的规则)。结果,它适用height: auto
(内容高度),符合规范。
另一方面,Firefox 现在接受父级的 Flex 高度作为子级百分比高度的参考。 IE11 和 Edge 也接受弹性高度。
此外,Chrome 将接受flex-grow
作为充分的家长参考如果与一起使用flex-basis
(任何数值都有效(auto https://stackoverflow.com/q/53870751/3597276不会),包括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>
四种解决方案
1. 指定所有父元素的高度
可靠的跨浏览器解决方案是指定所有父元素的高度。这可以防止丢失链接,基于 Webkit 的浏览器会认为丢失链接违反了规范。
注意min-height
and max-height
是不可接受的。一定是height
财产。
更多详细信息请参见此处:使用 CSSheight属性和百分比值 https://stackoverflow.com/a/31728799/3597276
2.CSS相对和绝对定位
Apply position: relative
给家长和position: absolute
给孩子。
给孩子定尺寸height: 100%
and width: 100%
,或使用偏移属性:top: 0
, right: 0
, bottom: 0
, left: 0
.
对于绝对定位,百分比高度无需在父级上指定高度即可工作。
3.删除不必要的HTML容器(推荐)
周围需要两个集装箱吗button
?为什么不删除.item
or .item-inner
, 或两者?虽然button元素有时会作为弹性容器失败 https://stackoverflow.com/q/35464067/3597276,它们可以是弹性项目。考虑制作button
的孩子.container
or .item
,并删除无偿的标记。
这是一个例子:
.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. 嵌套 Flex 容器(推荐)
摆脱百分比高度。摆脱表属性。摆脱vertical-align
。避免绝对定位。一直坚持使用 Flexbox 就可以了。
Apply display: flex
到弹性项目(.item
),使其成为一个弹性容器。这会自动设置align-items: stretch
,它告诉孩子(.item-inner
) 以扩展父级的完整高度。
重要提示:要使此方法起作用,请从弹性项目中删除指定的高度。如果孩子有指定的身高(例如height: 100%
),那么它将忽略align-items: stretch
来自父母。为了stretch
默认工作,孩子的身高必须计算为auto
(完整解释 https://stackoverflow.com/q/44878379/3597276).
试试这个(不改变 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 http://jsfiddle.net/y8mboo2s/3/