我想要一个有特定高度的垂直菜单。
每个子项必须填充父项的高度,并具有中间对齐的文本。
孩子的数量是随机的,所以我必须使用动态值。
Div.container
包含一定数量的子项(.item
),这些子项总是必须填充父项的高度。为了达到这个目的,我使用了flexbox。
为了使链接的文本与中间对齐,我使用display: table-cell
技术。但是使用表格显示需要使用100%的高度。
我的问题是.item-inner { height: 100% }
在webkit(Chrome)中不起作用。
有办法解决这个问题吗?
或者是否有不同的技术使所有.item
的文本垂直于中间对齐以填充父级的高度?
Example here jsFiddle, should be viewed in Firefox and Chrome
.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>
最佳答案
解决方案
使用嵌套的flex容器。
去掉百分比高度。删除表属性。去掉vertical-align
。避免绝对定位。一直用flexbox就行了。
将display: flex
应用于flex项(.item
),使其成为flex容器。这会自动设置align-items: stretch
,告诉子(.item-inner
)展开父对象的整个高度。
重要事项:从柔性项目中移除指定高度,以便此方法起作用。如果子对象具有指定的高度(例如height: 100%
),则它将忽略来自父对象的align-items: stretch
。要使默认值生效,孩子的身高必须计算为stretch
(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
解释
我的问题是
auto
在网络套件(Chrome)。
它不起作用,因为您使用的百分比高度不符合规范的传统实现。
10.5 Content height: the
.item-inner { height: 100% }
property百分比指定百分比高度。百分比是根据生成的框的高度计算的
包含块。如果包含块的高度不是
显式指定并且该元素不是绝对定位的,则该值计算为
height
。高度取决于其他属性的值。
换言之,要在流入子级上工作的百分比高度,父级必须具有设置的高度。
在代码中,顶级容器具有定义的高度:
auto
第三级容器具有定义的高度:
.container { height: 20em; }
但在它们之间,第二层容器——
.item-inner { height: 100%; }
——没有定义的高度。Webkit认为这是一个缺失的链接。.item
告诉Chrome:给我.item-inner
。Chrome会查看父级(height: 100%
)以供参考并响应:100%什么?我什么也没看到(忽略了那里的.item
规则)。因此,根据规范,它适用于flex: 1
(内容高度)。另一方面,Firefox现在接受父级的flex高度作为子级的百分比高度的参考。IE11和Edge也接受flex高度。
此外,如果与
height: auto
一起使用,Chrome将接受flex-grow
作为足够的父引用(任何数值都有效(flex-basis
不会),包括auto
)。然而,在撰写本文时,这个解决方案在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>
四种解决方案
一。指定所有父元素的高度
可靠的跨浏览器解决方案是指定所有父元素的高度。这可以防止丢失链接,基于Webkit的浏览器认为这违反了规范。
注意
flex-basis: 0
和min-height
是不可接受的。它必须是max-height
属性。更多详情请点击:Working with the CSS
height
property and percentage values2。CSS相对和绝对定位
将
height
应用于父对象,将position: relative
应用于子对象。使用
position: absolute
和height: 100%
调整子项的大小,或使用偏移属性:width: 100%
,top: 0
,right: 0
,bottom: 0
,left: 0
。使用绝对定位时,百分比高度在父级上不使用指定的高度。
三。删除不必要的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>
四。嵌套Flex容器(推荐)
去掉百分比高度。删除表属性。去掉
vertical-align
。避免绝对定位。一直用flexbox就行了。将
display: flex
应用于flex项(.item
),使其成为flex容器。这会自动设置align-items: stretch
,告诉子(.item-inner
)展开父对象的整个高度。重要事项:从柔性项目中移除指定高度,以便此方法起作用。如果子对象具有指定的高度(例如
height: 100%
),则它将忽略来自父对象的align-items: stretch
。要使默认值生效,孩子的身高必须计算为stretch
(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
关于css - Chrome/Safari无法填充Flex父级的100%高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53430581/