我想要一个具有特定高度的垂直菜单 .
每个孩子必须填写父母的高度并且具有中间对齐的文本 .
孩子的数量是随机的,所以我必须使用动态值 .
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>
4 回答
问题
它不起作用,因为你使用的百分比高度不符合规范的传统实现 .
换句话说,对于在流入子项上工作的百分比高度,父项必须具有设置的高度 .
在您的代码中,顶级容器具有已定义的高度:
.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
作为适当的父参考(任何值都有效,包括flex-basis: 0
) . 但是,在撰写本文时,此解决方案在Safari中失败 .解决方案
1. Specify a height on all parent elements
可靠的跨浏览器解决方案是在所有父元素上指定高度 . 这可以防止缺少链接,基于Webkit的浏览器认为这违反了规范 .
请注意,
min-height
和max-height
是不可接受的 . 它必须是height
属性 .更多细节:Working with the CSS height property and percentage values
2. CSS Relative & Absolute Positioning
将
position: relative
应用于父级,将position: absolute
应用于子级 .使用
height: 100%
和width: 100%
调整子项的大小,或使用偏移属性:top: 0
,right: 0
,bottom: 0
,left: 0
.使用绝对定位时,百分比高度在父级上没有指定高度的情况下工作 .
3. Remove unnecessary HTML containers (recommended)
button
周围是否需要两个容器?为什么不删除.item
或.item-inner
,或两者都删除?虽然button elements sometimes fail as flex containers,但它们可以是弹性项目 . 考虑使button
成为.container
或.item
的子项,并删除无偿标记 .这是一个例子:
4. Nested Flex Containers (recommended)
摆脱百分比高度 . 摆脱表属性 . 摆脱
vertical-align
. 避免绝对定位 . 只需坚持使用flexbox .将
display: flex
应用于弹性项目(.item
),使其成为弹性容器 . 这会自动设置align-items: stretch
,它告诉孩子(.item-inner
)扩展父级的完整高度 .重要说明:从弹性项中删除指定的高度,以使此方法起作用 . 如果孩子指定了一个身高(例如
height: 100%
),那么它将忽略来自父亲的align-items: stretch
. 要使stretch
默认工作,子项的高度必须计算为auto
(full explanation) .试试这个(不修改HTML):
jsFiddle
解决方案:在.item-inner中删除
height: 100%
并在.item中添加display: flex
演示:https://codepen.io/tronghiep92/pen/NvzVoo
我在iOS 8,9和10中遇到了类似的问题,上面的信息无法修复它,但是经过一天的努力,我确实发现了一个解决方案 . 当然,它不适用于所有人,但在我的情况下,我的物品堆放在一列中,当它应该是内容高度时,它的高度为0 . 将css切换为行并换行修复问题 . 这只适用于你有一个项目,他们堆叠,但因为我花了一天时间找到这个,我想我应该分享我的修复!
对于Mobile Safari有一个浏览器修复程序 . 你需要为iOS设备添加 -webkit-box .
防爆 .
如果您对父元素使用
align-items: stretch;
属性,请从子元素中删除height : 100%
.