解决方案
使用嵌套的弹性容器。
摆脱百分比高度。摆脱表属性。摆脱vertical-align。避免绝对定位。 一直坚持使用 flexbox。
将display: flex 应用于弹性项目(.item),使其成为弹性容器。这会自动设置 align-items: stretch,告诉子 (.item-inner) 扩展父的完整高度。
重要提示:从 flex 项中删除指定的高度以使此方法起作用。 如果子级具有指定的高度(例如 height: 100%),那么它将忽略来自父级的 align-items: stretch .要使stretch 默认工作,孩子的身高必须计算为auto (full explanation)。
试试这个(不更改 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 demo
说明
我的问题是.item-inner { height: 100% } 无法正常工作
webkit (Chrome)。
它不起作用,因为您使用百分比高度的方式不符合规范的传统实现。
10.5 Content height: the height property
百分比
指定百分比高度。百分比是根据生成框的高度计算的
包含块。如果包含块的高度不是
明确指定并且该元素不是绝对定位的,则该值计算为auto。
auto
高度取决于其他属性的值。
换句话说,要使百分比高度适用于流入子级,父级必须具有设定的高度。
在您的代码中,顶级容器具有定义的高度:.container { height: 20em; }
三级容器有一个定义的高度:.item-inner { height: 100%; }
但在它们之间,第二级容器 - .item - 没有定义的高度。 Webkit 认为这是一个缺失的链接。
.item-inner 告诉 Chrome:给我height: 100%。 Chrome 向父级 (.item) 寻求参考并回应:100% 的什么?我什么也没看到(忽略那里的flex: 1 规则)。因此,它根据规范应用height: auto(内容高度)。
另一方面,Firefox 现在接受父母的弹性高度作为孩子身高百分比的参考。 IE11 和 Edge 也接受弹性高度。
此外,如果与 flex-basis 结合使用,Chrome 将接受 flex-grow 作为足够的父引用(任何数值都有效(auto 无效),包括 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 和 max-height 是不可接受的。它必须是height 属性。
更多详情:Working with the CSS height property and percentage values
2. CSS 相对和绝对定位
将position: relative 应用于父级,将position: absolute 应用于子级。
使用height: 100% 和width: 100% 调整子级大小,或使用偏移属性:top: 0、right: 0、bottom: 0、left: 0。
使用绝对定位,百分比高度可以在没有指定高度的情况下在父级上工作。
3.删除不必要的 HTML 容器(推荐)
button 周围是否需要两个容器?为什么不删除.item 或.item-inner,或两者都删除?尽管button elements sometimes fail as flex containers,它们可以是弹性项目。考虑将button 设为.container 或.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。
将display: flex 应用于弹性项目(.item),使其成为弹性容器。这会自动设置 align-items: stretch,告诉子 (.item-inner) 扩展父级的整个高度。
重要提示:从 flex 项中删除指定的高度以使此方法起作用。 如果子项具有指定的高度(例如 height: 100%),那么它将忽略来自父项的 align-items: stretch .要使stretch 默认工作,孩子的身高必须计算为auto (full explanation)。
试试这个(不更改 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>