css - Chrome/Safari 未填充 100% 的 flex 父级高度

标签 css google-chrome webkit flexbox

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

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

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

部门 .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 ) 扩展父级的整个高度。

    重要提示:从 flex 元素中删除指定的高度以使此方法起作用。如果 child 指定了高度(例如 height: 100% ),那么它将忽略 align-items: stretch来自 parent 。对于 stretch默认工作, child 的高度必须计算为 auto (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

    说明

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



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

    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.



    换句话说,要使百分比高度适用于流入的 child , parent 必须有一个设定的高度。

    在您的代码中,顶级容器具有定义的高度:.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 也接受 flex 高度。

    此外,Chrome 将接受 flex-grow如果与 flex-basis 一起使用,作为足够的父引用(任何数值都有效( auto 无效),包括 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. 指定所有父元素的高度

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

    请注意 min-heightmax-height Not Acceptable 。它必须是 height属性(property)。

    更多详情:Working with the CSS height property and percentage values

    2. CSS 相对定位和绝对定位

    申请 position: relative给 parent 和 position: absolute给 child 。

    height: 100% 给 child 尺码和 width: 100% ,或使用偏移属性:top: 0 , right: 0 , bottom: 0 , left: 0 .

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

    3.删除不必要的HTML容器(推荐)
    button附近是否需要两个容器? ?为什么不删除 .item.item-inner ,或两者兼而有之?虽然 button elements sometimes fail as flex containers ,它们可以是 flex 元素。考虑制作 button .container的 child 或 .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: flex到 flex 元素( .item ),使其成为 flex 容器。这会自动设置 align-items: stretch ,它告诉子级 ( .item-inner ) 扩展父级的整个高度。

    重要提示:从 flex 元素中删除指定的高度以使此方法起作用。如果 child 指定了高度(例如 height: 100% ),那么它将忽略 align-items: stretch来自 parent 。对于 stretch默认工作, child 的高度必须计算为 auto (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 未填充 100% 的 flex 父级高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33636796/

    相关文章:

    javascript - PDF 的颜色仅适用于 Chrome

    javascript - 需要获得一个滑动 div 以留在页面上的同一位置(包括 JSFiddle)

    javascript - Jquery Mobile 在 Chrome 中不工作

    python - 增加QtWebKit每台主机的最大连接数

    html - PNG图像的CSS悬停效果

    objective-c - 如何改变WebView的网页位置?操作系统X

    html - 如何在鼠标悬停时修改和编辑图像颜色?

    JQuery UI 可拖动元素在 Chrome 中留下奇怪的痕迹

    html - 浏览器未在 HTTPS 中缓存图像(HTTP 工作正常)。即使使用缓存控制 : public

    html - 在具有粘性列的表上保留交替行阴影