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

2024-01-15

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

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

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

Div .container包含随机数量的子项 (.item)总是必须填充父级的高度。为了实现这一点,我使用了 Flexbox。

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

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

  1. 这个问题有解决办法吗?
  2. 或者是否有不同的技术来制作所有.item用垂直居中对齐的文本填充父级的高度?

这里的例子是 jsFiddle,应该在 Firefox 和 Chrome 中查看 http://jsfiddle.net/y8mboo2s/

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

Solution

使用嵌套的弹性容器。

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

Apply display: flex到弹性项目(.item),使其成为一个弹性容器。这会自动设置align-items: stretch,它告诉孩子(.item-inner) 以扩展父级的完整高度。

重要提示:要使此方法起作用,请从弹性项目中删除指定的高度。如果孩子有指定的身高(例如height: 100%),那么它将忽略align-items: stretch来自父母。为了stretch默认工作,孩子的身高必须计算为auto (完整解释 https://stackoverflow.com/q/44878379/3597276).

试试这个(不改变 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 演示 http://jsfiddle.net/y8mboo2s/3/


解释

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

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

10.5 内容高度:height财产 http://www.w3.org/TR/CSS22/visudet.html#the-height-property

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

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

换句话说,要使百分比高度适用于流入孩子,父母must有一个设定的高度。

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

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

但在它们之间,还有第二层容器——.itemdoes not有规定的高度。 Webkit 认为这是一个缺失的环节。

.item-inner正在告诉 Chrome:give me height: 100%。 Chrome 会向父级 (.item)供参考并回应:100% 什么?我什么也没看到(忽略flex: 1那里的规则)。结果,它适用height: auto(内容高度),符合规范。

另一方面,Firefox 现在接受父级的 Flex 高度作为子级百分比高度的参考。 IE11 和 Edge 也接受弹性高度。

此外,Chrome 将接受flex-grow作为充分的家长参考如果与一起使用flex-basis(任何数值都有效(auto https://stackoverflow.com/q/53870751/3597276不会),包括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-height and max-height是不可接受的。一定是height财产。

更多详细信息请参见此处:使用 CSSheight属性和百分比值 https://stackoverflow.com/a/31728799/3597276

2.CSS相对和绝对定位

Apply position: relative给家长和position: absolute给孩子。

给孩子定尺寸height: 100% and width: 100%,或使用偏移属性:top: 0, right: 0, bottom: 0, left: 0.

对于绝对定位,百分比高度无需在父级上指定高度即可工作。

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

周围需要两个集装箱吗button?为什么不删除.item or .item-inner, 或两者?虽然button元素有时会作为弹性容器失败 https://stackoverflow.com/q/35464067/3597276,它们可以是弹性项目。考虑制作button的孩子.container or .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 就可以了。

Apply display: flex到弹性项目(.item),使其成为一个弹性容器。这会自动设置align-items: stretch,它告诉孩子(.item-inner) 以扩展父级的完整高度。

重要提示:要使此方法起作用,请从弹性项目中删除指定的高度。如果孩子有指定的身高(例如height: 100%),那么它将忽略align-items: stretch来自父母。为了stretch默认工作,孩子的身高必须计算为auto (完整解释 https://stackoverflow.com/q/44878379/3597276).

试试这个(不改变 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 http://jsfiddle.net/y8mboo2s/3/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Chrome / Safari 未填充 Flex 父级的 100% 高度 的相关文章

  • 当鼠标悬停在链接上时,如何在链接旁边创建弹出框?

    这是我想要实现的 我的网页上显示了两个超链接 a href http foo com foo a a href http bar com bar a 我还有两个对 div 链接的描述 div foo means foo div div ba
  • 设置overflow-y可见,而overflow-x为auto,以便内容可以垂直溢出父容器

    我在用着position absolute and position relative如果将其父级悬停在图像上 则在图像上显示文本 文本和图像父 div 所在的容器设置为overflow x auto 使其具有水平滚动条 我想要看起来垂直溢
  • stripe checkout css内容策略错误

    我正在尝试创建一种形式条纹结账 https stripe com docs checkout在我的 Ionic 应用程序中 我创建了一个指令 将表单植入到我的内容视图中 但是当我运行它时 CSS 因违反内容策略而失败 checkout js
  • 将 html 转换为 pdf 时防止表格单元格跨页破坏

    使用 Google Apps 脚本 我有一个 html 模板 我填写该模板 然后以 pdf 形式发送 通过传真和 或电子邮件 该模板包括一个带有问题 答案的两列表格 如果行数足够多 表格会在pdf中跨页分页 并且分页符通常发生在单元格的中间
  • 在导航栏下方添加背景图片

    我想在导航栏下方添加背景图像 具有完整窗口大小的宽度 它不应覆盖整个页面长度 而是从导航栏菜单下方开始 一直向下直到特定的指定高度 但宽度是满的 我参考了以下内容 但仍然没有结果 在 Twitter Bootstrap 中的导航栏下方启动背
  • React JS - 单击时更改颜色并将默认颜色放在所有其他颜色上

    我有 x 个渲染数文章预览依赖于 API 调用的组件 div div Object keys images map index i gt return div div
  • 监听浏览器宽度以进行响应式网页设计?

    我正在努力使我的网站适合移动设备 我想知道浏览器窗口的大小 以便当它比 728px 窄时我可以执行某些操作 而当它大于 728px 时我可以执行其他操作 这必须考虑到调整 PC 上的窗口大小以及在手机中从纵向模式更改为横向模式 如何才能做到
  • IE bug:具有不透明背景色的绝对定位元素

    我有一个绝对定位的 DIV 需要捕获 onclick 事件 事实证明 在 IE7 中 DIV 似乎没有诸如单击甚至光标之类的 足迹 例如 div width 200px height 200px position absolute bord
  • 如何修复“没有这样的文件或目录,lstat 'scss/'”?

    我正在尝试遵循 youtube 上的简单教程他尝试使用终端运行 npm 脚本 sass 文件 当我执行命令时npm 运行 sass显示错误消息错误 ENOENT 没有这样的文件或目录 lstat scss 我认为问题在于文件的路径或文件的权
  • 为什么我的图像下方有空间? [复制]

    这个问题在这里已经有答案了 图像在下面获得了神秘的空白空间 即使padding 0 margin 0被应用 示范 http jsfiddle net cLETP 红色边框应该包围图像 但底部有空间 造成这种情况的原因是什么 如何删除该空间
  • 单击回车键上的锚标记链接

    我有一个像这样的锚标签 a class btn btn danger href Continue a 它位于弹出窗口内 我需要按 Enter 键单击此链接 我尝试过以下代码 但它对我不起作用 document ready function
  • 如何保留用户的输入打印?

    我正在尝试添加用户的评论 所以我只是尝试读取输入并将其发送以进行打印 但问题是 一旦我刷新页面或输入另一个输入 打印的输入就会消失 因此 即使刷新页面或重新输入新评论 我也希望始终保持所有用户的显示 代码 div div
  • 为什么复制功能在 setTimeout 中不起作用?

    当我尝试时 Chrome 会抱怨copy inside setTimeout setTimeout function copy a 0 Uncaught ReferenceError copy is not defined at
  • 理解 z-index:该元素如何出现在其父级同级元素的前面?

    为什么当我删除时红色 div 位于绿色 div 前面z index from wrapperRed 感觉像z index是沿着链条向上继承的 如果我改变z index将绿色 div 更改为 6 即使删除第一句中描述的行后 它仍保留在红色 d
  • 单击导航项锚链接时如何关闭切换菜单

    请看我的FIDDLE http jsfiddle net ayhpp8ax 我有一个带有 响应式 导航菜单 带有指向页面上元素的锚链接 的 1 页网站 当浏览器视口小于特定宽度 在我的情况下为 767px 时 使用此 javascript
  • Sass:@use 出错,未定义变量

    我正在使用 Sass 并且想要使用 use关键字而不是 import 因为 import有很多问题 另外只有dart sass支持这个功能 我将node sass改为dart sass 然而 问题出现了 我原来的代码 import carb
  • 如何在其他div id的悬停中使用div显示块

    如何打开div悬停时标记href tag 这是我在悬停 href 标签上显示 div 标签的代码 Services is id of href tag Services is id of div tag Service hover Serv
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 如何使用 JavaScript 或 jQuery 克隆 HTML 元素的样式对象?

    我正在尝试克隆元素的样式对象 这应该允许我在更改后重置所述元素的样式 例如 el style left 50px curr style left 50px Modify the elements style The cloned style
  • css3按钮背景颜色无限过渡

    有没有办法仅使用 css3 使按钮的背景颜色从灰色渐变为蓝色 然后又回到灰色 一个很好的例子是默认操作按钮是可可 我知道这可以在 javascript 中完成 但我宁愿只使用 css 来完成此操作 您好 我已经通过 CSS3 动画制作了按钮

随机推荐