当前位置: 首页 > 面试题库 >

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

江丰羽
2023-03-14
问题内容

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

每个孩子都必须填充父母的身高,并且中间对齐文本。

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

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

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

我的问题是.item-inner { height: 100% }无法在webkit(Chrome)中使用。

  1. 有解决此问题的方法吗?
  2. 还是有一种不同的技术可以使所有.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="item-inner">
    
      <a>Button</a>
    
    </div>
    
    <div class="item-inner">
    
      <a>Button</a>
    
    </div>
    
    <div class="item-inner">
    
      <a>Button</a>
    
    </div>
    

问题答案:

使用嵌套的伸缩容器。

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

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

说明

我的问题是.item-inner { height: 100% }无法在webkit(Chrome)中使用。

它不起作用,因为您使用的百分比高度与规范的传统实现方式不一致。

10.5内容高度:height属性

percent
指定百分比高度。相对于生成的盒子的包含块的高度计算百分比。如果未明确指定包含块的高度,并且此元素未绝对定位,则该值将计算为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也接受弯曲高度。

此外, 如果与 (任何数字值(不会),包括在内) 结合使用,Chrome会接受flex-grow作为适当的父级参考。但是,在撰写本文时,此解决方案在Safari中失败。 flex-basisautoflex-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;

}


<div id="outer">

  <div id="middle">

    <div id="inner">

      INNER

    </div>

  </div>

</div>

四种解决方案

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

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

请注意,min-heightmax-height是不可接受的。它必须是height属性。

此处有更多详细信息: 使用CSS
height属性和百分比值

2. CSS相对和绝对定位

适用position: relative于父母和position: absolute孩子。

尺寸与孩子height: 100%width: 100%,或使用污损特性:top: 0right: 0bottom: 0left: 0

通过绝对定位,百分比高度可以在父级上没有指定高度的情况下工作。

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

是否需要两个容器button?为什么不删除.item.item- inner,或两者都不删除?尽管button元素有时无法作为flex容器使用,但它们可以是flex项目。考虑让或成为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>

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

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

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


 类似资料:
  • 我想有一个垂直的菜单,有一个特定的高度。 每个子级必须填充父级的高度并具有中间对齐的文本。 孩子的数量是随机的,所以我必须使用动态值。 Div包含随机数的子级(),这些子级总是必须填充父级的高度。为了实现这一点,我使用了FlexBox。 为了使链接中的文本对齐,我使用了技术。但是使用表格显示需要使用100%的高度。 我的问题是在webkit(Chrome)中不工作。 有解决此问题的方法吗? 或者是

  • 问题内容: +--------------------+ | | | | | | | | | 1 | | | | | | | | | +--------------------+ | | | | | | | | | 2 | | | | | | | | | +--------------------+ 如上所示的(1)的内容是未知的,因为它在动态生成的页面中可能会增加或减少。如上所示,第二个div(

  • 问题内容: 使用HTML / CSS,如何制作宽度和/或高度为其父元素的100%并且仍然具有适当的填充或边距的元素? 所谓“适当的”我的意思是,如果我的父元素是高大的,我指定用我所期望的,我应该得到一个高的元素与所有各方,很好地集中在父元素。 现在,我知道这不是标准盒模型指定它应该工作的方式(尽管我想确切地知道为什么),所以显而易见的答案不起作用: 但是在我看来,必须有某种方法可以可靠地为任意大小

  • 我试图理解我的意外行为: 容器中有一个最大高度为100%的元素,该容器也使用了最大高度,但意外的是,子元素溢出了父元素: 测试用例:http://jsfiddle.net/bq4Wu/16/ 但是,如果为父级指定了明确的高度,则这是固定的: 测试用例:http://jsfiddle.net/bq4Wu/17/ 有人知道第一个例子中孩子为什么不尊重父母的最大身高吗?为什么需要明确的高度?

  • 但是,它在Safari中并不起作用。但是如果我们将中的高度从更改为,我们将观察到拆分器(从上到下到)变得可拖动。这意味着在Safari中不起作用。 有没有人知道如何修改代码,使拆分器在Chrome和Safari中都能工作? 编辑1:

  • 问题内容: 我的HTML文档中有一个iframe,但遇到了一些麻烦。 我还在页面顶部有一个URL栏(固定位置元素),当用户滚动时,URL栏应随用户使用。很好 我希望iframe可以填充剩余空间,但不会被网址栏覆盖。 这就是我在说的。http://s75582.gridserver.com/Ls 如何解决此问题,以使URL栏不覆盖页面的一部分?当我尝试在主体中设置padding时,它只会创建一个额外