css - Chrome/Safari无法填充Flex父级的100%高度

标签 css css3 google-chrome webkit flexbox

我想要一个有特定高度的垂直菜单。
每个子项必须填充父项的高度,并具有中间对齐的文本。
孩子的数量是随机的,所以我必须使用动态值。
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: 0min-height是不可接受的。它必须是max-height属性。
更多详情请点击:Working with the CSS height property and percentage values
2。CSS相对和绝对定位
height应用于父对象,将position: relative应用于子对象。
使用position: absoluteheight: 100%调整子项的大小,或使用偏移属性:width: 100%top: 0right: 0bottom: 0left: 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/

相关文章:

javascript - 本地文件夹中的 console.log 问题

javascript - Firefox 不处理 keyCode。它在调试器中将变量显示为矩阵

html - 图像 slider 过度滚动

css - 如何使用媒体查询更改主机的CSS :( polymer )

css - 在网页上使用 Avant Garde BK BT 字体?

flash - Chrome上的Flash是否与Firefox相同?

javascript - 在 CSS 网格布局中使用 em 或百分比

jquery - 从下拉选择中选择选项时更改 div 内容

javascript - 如果 wrapper 元素是 -4000 px left alert

css - flex 自动填充空间,不拉伸(stretch)