解
使用嵌套的伸缩容器。
摆脱百分比高度。摆脱表属性。摆脱vertical-align。避免绝对定位。一直坚持使用flexbox。
应用于display: flexflex项目(.item),使其成为flex容器。这会自动设置align-items: stretch,告诉孩子(.item-inner)扩大父母的整个身高。
重要提示:从弹性项目中删除指定的高度,此方法才能起作用。如果孩子有指定的身高(例如height: 100%),那么它将忽略align-items: stretch来自父母的身高。为了使stretch默认设置生效,孩子的身高必须计算为auto (完整说明)。
试试看(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演示
说明
我的问题是.item-inner { height: 100% }无法在webkit(Chrome)中使用。
它不起作用,因为您使用的百分比高度与规范的传统实现方式不一致。
10.5内容高度:height属性
percent
指定百分比高度。相对于生成的盒子的包含块的高度计算百分比。如果未明确指定包含块的高度,并且此元素未绝对定位,则该值将计算为auto。
自动
高度取决于其他属性的值。
换句话说,要使百分比高度适用于流入儿童,父级必须具有设定的高度。
在您的代码中,顶级容器具有定义的高度: .container { height: 20em; }
第三级容器具有定义的高度: .item-inner { height: 100%; }
但是在它们之间,二级容器– .item– 并不定义的高度。Webkit将其视为缺少的链接。
.item-inner告诉Chrome:给我height: 100%。Chrome浏览器会向父级(.item)供参考并做出回应:100%是什么?我什么也没看到(忽略flex: 1那里的规则)。结果,height: auto根据规范适用(内容高度)。
另一方面,Firefox现在接受父级的flex高度作为孩子的百分比高度的参考。IE11和Edge也接受弯曲高度。
此外,如果与(任何数字值(不会),包括在内)结合使用,Chrome将接受flex-grow作为适当的父级参考。但是,在撰写本文时,此解决方案在Safari中失败。flex-basisautoflex-basis: 0
#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属性。
此处更多详细信息: 使用CSS height属性和百分比值
2. CSS相对和绝对定位
适用position: relative于父母和position: absolute孩子。
使用height: 100%和调整子项的大小width: 100%,或使用offset属性:top: 0,right: 0,bottom: 0,left: 0。
通过绝对定位,百分比高度可以在父级上没有指定高度的情况下工作。
3.删除不必要的HTML容器(推荐)
是否需要两个容器button?为什么不删除.item或.item-inner,或两者都不删除?尽管button元素有时会作为弹性容器失败,但它们可以是弹性项目。考虑让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: flexflex项目(.item),使其成为flex容器。这会自动设置align-items: stretch,告诉孩子(.item-inner)扩大父母的整个身高。
重要提示:从弹性项目中删除指定的高度,此方法才能起作用。如果孩子有指定的身高(例如height: 100%),那么它将忽略align-items: stretch来自父母的身高。为了使stretch默认设置生效,孩子的身高必须计算为auto (完整说明)。
试试看(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>