Chrome / Safari无法填充100%高度的父级parent [英] Chrome / Safari not filling 100% height of flex parent

查看:206
本文介绍了Chrome / Safari无法填充100%高度的父级parent的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



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



Div 。 container 包含随机数的子元素( .item ),总是必须填充父元素的高度。为了实现我使用flexbox。



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



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


  1. 这个问题有解决方法吗?

  2. 或者有一种不同的技术,使所有 .item 填充父文本的高度,文本垂直对齐到中间?

这里的例子jsFiddle,应该被查看在Firefox和Chrome中



  .container {height:20em;显示: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>按钮< / a> < / div> < / div> < div class =item> < div class =item-inner> < a>按钮< / a> < / div> < / div> < div class =item> < div class =item-inner> < a>按钮< / a> < / div> < / div>< / div>  

解决方案

问题




我的问题是 .item-inner {height:100% }


它不工作,因为你'


10.5内容高度: height 属性



百分比
指定百分比高度。该百分比是相对于生成的框的
包含块的高度计算的。如果包含块的高度不是
,并且该元素不是绝对定位,则该值计算为 auto



自动
高度取决于其他属性的值。




在您的代码中, ,顶层容器具有定义的高度: .container {height:20em; }



第三级容器具有定义的高度: .item-inner {height:100%; }



但是在它们之间,二级容器– .item 不具有定义的高度。 Webkit认为这是一个缺失的链接。



.item-inner 告诉Chrome: code> height:100% 。 Chrome会查找父级( .item )以供参考,并回应: 100%的内容?我没有看到任何(忽略 flex:1 规则)。因此,它会根据规范应用 height:auto (content height)。



<另一方面,现在接受父级的flex高度作为孩子的百分比高度的参考。 IE11和Edge也接受flex高度。



此外,Chrome将接受 flex-grow 如果与 flex-basis (任何值都有效,包括 flex-basis:0 )。在这篇文章中,这个解决方案在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>  






解决方案



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



一个可靠的跨浏览器解决方案是在所有父元素上指定高度。



注意 min-height max-height 是不可接受的。必须是 height 属性。



CSS相对和绝对定位



位置:相对应用于父级和 position:absolute



使用 height:100%设置绝对定位的子尺寸width:100% / code>,或使用偏移属性: top:0 right:0 bottom:0 left:0



百分比高度在父级上没有指定高度。



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



按钮< c>?为什么不删除 .item .item-inner 或两者?虽然 按钮元素有时会作为弹性容器失败,但它们可以是flex项目。考虑使按钮 .container .item





-lang =jsdata-hide =truedata-console =truedata-babel =false>

  .container {height:20em;显示:flex; flex-direction:column; border:5px solid black} a {flex:1;背景:橙色; border-bottom:1px solid white;显示:flex; / *嵌套flex容器(用于对齐文本)* / align-items:center; / *中心文本垂直* / justify-content:center; / *中心文本水平* /}  

 < div class =container> < a>按钮< / a> < a>按钮< / a> < a> Button< / a>< / div>  



4。嵌套Flex容器(推荐)



删除百分比高度。删除表属性。除去 vertical-align 。避免绝对定位。



应用 display:flex flex item( .item ),使它成为一个flex容器。这会自动设置 align-items:stretch ,它告诉孩子( .item-inner )展开全高



  .container {display:flex; flex-direction:column; height:20em; border:5px solid black} .item {display:flex; / * new;嵌套的flex容器* / flex:1; border-bottom:1px solid white;}。item-inner {display:flex; / * new;嵌套flex容器* / flex:1; / * new * / / * height:100%; <  -  remove;不必要* / / * width:100%; <  -  remove;不必要* / / * display:table; <  -  remove;不必要* /} a {display:flex; / * new;嵌套的flex容器* / flex:1; / * new * / align-items:center; / * new;垂直中心文本* /背景:橙色; / * display:table-cell; <  -  remove;不必要* / / * vertical-align:middle; <  -  remove;不必要* /}  

 < div class = > < div class =item> < div class =item-inner> < a>按钮< / a> < / div> < / div> < div class =item> < div class =item-inner> < a>按钮< / a> < / div> < / div> < div class =item> < div class =item-inner> < a>按钮< / a> < / div> < / div>< / div>  



jsFiddle






更多信息



如何在CSS中正常工作的百分比:





Firefox和IE使用父级弹性高度作为子级百分比高度参考的示例: $ b


I want to have a vertical menu with a specific height.

Each child must fill the height of the parent and have middle-aligned text.

The number of children is random, so I have to work with dynamic values.

Div .container contains a random number of children (.item) that always have to fill the height of the parent. To achieve that I used flexbox.

For making links with text aligned to the middle I am using display: table-cell technique. But using table displays requires using a height 100%.

My problem is that .item-inner { height: 100% } is not working in webkit (Chrome).

  1. Is there a fix for this problem?
  2. Or is there a different technique to make all .item fill the height of the parent with text vertical aligned to middle?

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>

解决方案

The Problem

My problem is that .item-inner { height: 100% } is not working in webkit (Chrome).

It's not working because you're using percentage height in a way that doesn't conform with the traditional implementation of the spec.

10.5 Content height: the height property

percentage
Specifies a percentage height. The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly and this element is not absolutely positioned, the value computes to auto.

auto
The height depends on the values of other properties.

In other words, for percentage height to work on an in-flow child, the parent must have a set height.

In your code, the top-level container has a defined height: .container { height: 20em; }

The third-level container has a defined height: .item-inner { height: 100%; }

But between them, the second-level container – .itemdoes not have a defined height. Webkit sees that as a missing link.

.item-inner is telling Chrome: give me height: 100%. Chrome looks to the parent (.item) for reference and responds: 100% of what? I don't see anything (ignoring the flex: 1 rule that is there). As a result, it applies height: auto (content height), in accordance with the spec.

Firefox, on the other hand, now accepts a parent's flex height as a reference for the child's percentage height. IE11 and Edge accepts flex heights, as well.

Also, Chrome will accept flex-grow as an adequate parent reference if used in conjunction with flex-basis (any value works, including flex-basis: 0). As of this writing, however, this solution fails in 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>


Solutions

1. Specify a height on all parent elements

A reliable cross-browser solution is to specify a height on all parent elements. This prevents missing links, which Webkit-based browsers consider a violation of the spec.

Note that min-height and max-height are not acceptable. It must be the height property.

2. CSS Relative & Absolute Positioning

Apply position: relative to the parent and position: absolute to the child.

Size the absolutely positioned child with height: 100% and width: 100%, or use the offset properties: top: 0, right: 0, bottom: 0, left: 0.

With absolute positioning, percentage height works without a specified height on the parent.

3. Remove unnecessary HTML containers (Recommended)

Is there a need for two containers around button? Why not remove .item or .item-inner, or both? Although button elements sometimes fail as flex containers, they can be flex items. Consider making button a child of .container or .item, and removing gratuitous mark-up.

Here's an example:

.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. Nested Flex Containers (Recommended)

Get rid of percentage heights. Get rid of table properties. Get rid of vertical-align. Avoid absolute positioning. Just stick with flexbox all the way through.

Apply display: flex to the flex item (.item), making it a flex container. This automatically sets align-items: stretch, which tells the child (.item-inner) to expand the full height of the parent.

Try this (no changes to 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


More Information

How percentage heights normally work in CSS:

Examples of Firefox and IE using a parent's flex height as reference for a child's percentage height:

这篇关于Chrome / Safari无法填充100%高度的父级parent的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆