我想要一个具有特定高度的垂直菜单。

每个孩子必须填充父级的高度并具有中间对齐的文本。

孩子的数量是随机的,所以我必须使用动态值。

Div .container包含随机数量的子级(.item),这些子级必须始终填充父级的高度。为此,我使用了flexbox。

我使用display: table-cell技术来使文本与中间对齐的链接。但是使用表格显示需要使用100%的高度。

我的问题是.item-inner { height: 100% }在webkit(Chrome)中不起作用。


是否已解决此问题?
或者是否有其他方法可以使所有.item的文字垂直于中间对齐而填满父级的高度?



 .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> 




评论

现在已修复-bugs.chromium.org/p/chromium/issues/detail?id=426898

这与OP没有特别的关系,但对于因“野生动物园显示绝对高度100%无法正常工作”或类似原因而落在此处的Google员工来说可能与此有关。我在flex容器中有一个像这样的元素,必须指定top:0和left:0才能使它按预期显示。

@vsync尚未修复:stackoverflow.com/questions/46226298/…

#1 楼

解决方案

使用嵌套的伸缩容器。

消除百分比高度。摆脱表属性。摆脱vertical-align。避免绝对定位。一直坚持使用flexbox。

display: flex应用于flex项目(.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

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也可以接受弯曲高度。 。但是,在撰写本文时,此解决方案在Safari中失败。




 flex-grow 

 flex-basis 






四种解决方案

1。在所有父元素上指定高度

一种可靠的跨浏览器解决方案是在所有父元素上指定高度。这样可以防止丢失链接,基于Webkit的浏览器会认为这些链接违反了规范。

请注意,autoflex-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; }属性。

更多详细信息在这里:使用CSS <div id="outer"> <div id="middle"> <div id="inner"> INNER </div> </div> </div>属性和百分比值

2。 CSS相对和绝对定位

min-height应用于父级,将max-height应用于子级。

使用heightheight调整子项的大小,或使用偏移属性:position: relativeposition: absoluteheight: 100%width: 100%。父母。

3.删除不必要的HTML容器(推荐)

top: 0周围是否需要两个容器?为什么不删除right: 0bottom: 0或同时删除两者?尽管left: 0元素有时会作为flex容器失败,但它们可以是flex物品。考虑让button成为.item.item-inner的子代,并删除不必要的标记。

下面是一个示例:

 button 

 button 





4。嵌套的Flex容器(推荐)

消除百分比高度。摆脱表属性。摆脱.container。避免绝对定位。一直坚持使用flexbox。

.item应用于flex项目(.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 */ }),使其成为flex容器。这将自动设置<div class="container"> <a>Button</a> <a>Button</a> <a>Button</a> </div>,该值告诉子级(vertical-align)扩展父级的整个高度。如果孩子有指定的身高(例如display: flex),那么它将忽略来自父母的.item。为了使align-items: stretch默认工作,孩子的身高必须计算为.item-inner(完整说明)。

尝试一下(HTML不变):




 height: 100% 

 align-items: stretch 





jsFiddle

评论


我使用height:auto解决了我的问题

– Alfrex92
18年11月25日在5:24

从这篇好文章的解释链接中摘录的一些话-“ align-items:Stretch”使flex子级在容器的横轴上扩展-即将子级拉伸到高度,flex容器应具有flex-direction作为行。

–小小为什么
19年5月24日在19:04

我可以确认使用嵌套的flex容器效果最好。我们在菜单中不一致地使用了flexbox。代替在父容器上使用flex:1和display:flex,我们在某些地方使用height:100%。替换了相应的定义后,所有操作均按预期进行。感谢@Michael_B的提示! :)

–locbit
19年5月27日在15:12

@ JamesHarrington,CSS随时间增长并且很复杂;-)

–DerMike
19/09/24'9:54

每个解决方案应该是不同的答案。如何以这种方式在特定解决方案中投票?

– Jp_
5月12日14:25

#2 楼

为我工作的容器指定flex属性:

.container {
    flex: 0 0 auto;
}


这可以确保高度设置且不会增加。

评论


为我修复它!真是救命稻草。

–克里斯·海斯(Chris Hayes)
9月10日下午14:40

#3 楼

解决方案:删除.item-inner中的height: 100%并在.item中添加display: flex

演示:https://codepen.io/tronghiep92/pen/NvzVoo

评论


谢谢,这对我有帮助。有弹性的孩子会自动拉伸到容器的高度吗?这就是为什么这可行吗?

–里斯·肯尼(Reece Kenney)
17年8月25日在10:18

@ReeceKenney,是的,您的问题。这在我的答案中得到了解释。请参阅解决方案#4。

–迈克尔·本杰明(Michael Benjamin)
17年8月29日在11:25

#4 楼

对于Mobile Safari,有一个浏览器修复程序。您需要为iOS设备添加-webkit-box。

例如。

display: flex;
display: -webkit-box;
flex-direction: column;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
align-items: stretch;


如果对父元素使用align-items: stretch;属性,从子元素中删除height : 100%

评论


天哪,非常感谢你,让我免于头痛!显示:-webkit-box;正是我所需要的。事实证明,即使在2020年末,iOS设备仍然没有可预测的Flex支持

–巨款
9月25日17:58

#5 楼

我在iOS 8、9和10中遇到过类似的问题,上面的信息无法解决,但是经过一天的努力,我确实找到了解决方案。当然,它不适用于所有人,但在我的情况下,我的物品堆放在一列中,当它应该为内容高度时,其高度为0。将CSS切换为行换行可解决此问题。仅当您有一个项目并且将它们堆叠时,此方法才有效,但是由于花了我一天的时间才发现此问题,所以我认为我应该分享我的解决方法!

.wrapper {
    flex-direction: column; // <-- Remove this line
    flex-direction: row; // <-- replace it with
    flex-wrap: wrap; // <-- Add wrapping
}

.item {
    width: 100%;
}


#6 楼

我有一个类似的错误,但是使用固定数字表示高度而不是百分比。它也是体内的弹性容器(没有指定高度)。似乎在Safari上,由于某种原因,我的flex容器的高度为9px,但在所有其他浏览器中,它都显示了样式表中指定的正确100px高度。

通过在CSS类中添加heightmin-height属性,我设法使其正常工作。

以下内容对我在Safari 13.0.4和Chrome 79.0上均有效.3945.130:

.flex-container {
  display: flex;
  flex-direction: column;
  min-height: 100px;
  height: 100px;
}


希望有帮助!