无法滚动到溢出容器的弹性项目的顶部

jej*_*s0n 206 html css css3 browser-bugs flexbox

因此,在尝试使用flexbox创建一个有用的模式时,我发现了什么似乎是一个浏览器问题,我想知道是否有一个已知的修复或解决方法 - 或者如何解决它的想法.

我想解决的问题有两个方面.首先,使模态窗口垂直居中,这可以按预期工作.第二个是让模态窗口滚动 - 外部,所以整个模态窗口滚动,而不是其中的内容(这样你就可以有下拉列表和其他可以扩展到模态边界之外的UI元素 - 像自定义日期选择器等)

但是,当将垂直居中与滚动条组合时,模态的顶部在开始溢出时可能无法进入.在上面的示例中,您可以调整大小以强制溢出,这样做可以让您滚动到模态的底部,但不能滚动到顶部(第一段被截断).

这是示例代码的链接(高度简化)

https://jsfiddle.net/dh9k18k0/2/

.modal-container {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.5);
  overflow-x: auto;
}
.modal-container .modal-window {
  display: -ms-flexbox;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  // Optional support to confirm scroll behavior makes sense in IE10
  //-ms-flex-direction: column;
  //-ms-flex-align: center;
  //-ms-flex-pack: center;
  height: 100%;
}
.modal-container .modal-window .modal-content {
  border: 1px solid #ccc;
  border-radius: 4px;
  background: #fff;
  width: 100%;
  max-width: 500px;
  padding: 10px
}
Run Code Online (Sandbox Code Playgroud)

这个效果(当前)Firefox,Safari,Chrome和Opera ..如果你在IE10供应商前缀css中发表评论,它在IE10中的表现确实有趣 - 我还没有在IE11中进行测试,但是假设行为与IE10相符.

任何想法都会很好.与已知问题的链接或此行为背后的推理也很有用.

Mic*_*l_B 386

问题

Flexbox使中心变得非常容易.

通过简单地应用align-items: centerjustify-content: center弹性容器,您的弹性项目将垂直和水平居中.

但是,当flex项大于flex容器时,此方法存在问题.

如问题中所述,当柔性物品溢出容器时,顶部变得不可访问.

在此输入图像描述

对于水平溢出,左侧部分变得不可访问(或右侧部分,以RTL语言).

这是一个LTR容器有justify-content: center三个flex项的例子:

在此输入图像描述

有关此行为的说明,请参阅此答案的底部.


解决方案#1

要解决此问题,请使用flexbox自动边距,而不是justify-content.

对于auto边距,溢出的弹性项目可以垂直和水平居中,而不会失去对其任何部分的访问.

因此,而不是Flex容器上的此代码:

#flex-container {
    align-items: center;
    justify-content: center;
}
Run Code Online (Sandbox Code Playgroud)

在flex项上使用此代码:

.flex-item {
    margin: auto;
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

修订演示


解决方案#2(大多数浏览器尚未实现)

safe值添加到关键字对齐规则中,如下所示:

justify-content: safe center
Run Code Online (Sandbox Code Playgroud)

要么

align-self: safe center
Run Code Online (Sandbox Code Playgroud)

CSS Box Alignment Module规范:

4.4.溢出对齐:将safeunsafe关键字和滚动安全限制

当[flex item]大于[flex容器]时,它将溢出.某些对齐模式,如果在这种情况下受到尊重,可能会导致数据丢失:例如,如果侧边栏的内容居中,当它们溢出时,它们可能会将其部分框发送到视口的起始边缘,而不能滚动到.

要控制这种情况,可以显式指定溢出对齐模式.Unsafealignment在溢出情况下遵循指定的对齐模式,即使它导致数据丢失,而safe对齐会在溢出情况下更改对齐模式以避免数据丢失.

默认行为是在可滚动区域内包含对齐主题,但在撰写本文时,此安全功能尚未实现.

safe

如果[flex item]的大小溢出[flex容器],则[flex item]会对齐,就像对齐模式为[ flex-start]一样.

unsafe

无论[flex item]和[flex container]的相对大小如何,都会遵循给定的对齐值.

注意:Box Alignment Module适用于多个盒子布局模型,而不仅仅是flex.因此,在上面的规范摘录中,括号中的术语实际上表示"对齐主题","对齐容器"和" start".我使用特定于flex的术语来关注这个特定问题.


MDN滚动限制的说明:

Flex项目注意事项

与CSS中的其他居中方法不同,Flexbox的对齐属性可以"真正"居中.这意味着flex项目将保持居中,即使它们溢出Flex容器.

这有时会出现问题,但是,如果它们溢出页面的顶部边缘或左​​边缘[...],因为你无法滚动到那个区域,即使那里有内容!

在将来的版本中,对齐属性将扩展为具有"安全"选项.

现在,如果这是一个问题,你可以改为使用边距来实现居中,因为它们会以"安全"的方式响应并且如果它们溢出则停止居中.

不要使用align-属性,只需将auto边距放在您希望居中的弹性项目上.

而不是justify-属性,将自动边距放在Flex容器中第一个和最后一个flex项的外边缘上.

auto利润率将"灵活",并承担剩余的空间,围绕柔性物品时,有剩余的空间,并切换到正常的排列时,没有.

但是,如果您尝试justify-content在多行Flexbox中替换基于边距的居中,则可能不幸,因为您需要将边距放在每行的第一个和最后一个弹性项目上.除非您能提前预测哪些项目最终会在哪一行上进行,否则您无法在主轴中可靠地使用基于边距的居中来替换该justify-content属性.

  • 要解决IE11中的问题:在flex容器中添加`align-items:flex-start`并为flex项保留`margin:auto`. (9认同)
  • “安全中心”很棒。但到目前为止仅在 Firefox 中受支持:https://caniuse.com/#search=flex%20safe (5认同)
  • 是的,这是一个更好的解决方案,并感谢您提供额外的宝贵见解. (4认同)
  • @Daniel,我刚刚测试了IE11中的代码.没有什么是无法进入的.事实上,问题中描述的问题甚至不存在于IE11中.您可能指的是仅在IE11中发生的文本溢出.这是另一个问题的另一个问题. (2认同)
  • 当使用flex-direction时,这对我不起作用:column; (2认同)

jej*_*s0n 20

好吧,正如墨菲定律所说的那样,我在发布这个问题后所做的阅读产生了一些结果 - 没有完全解决,但仍然有些有用.

在发布之前,我在min-height上玩了一下,但是并没有意识到规范中相当新的固有尺寸限制.

http://caniuse.com/#feat=intrinsic-width

添加min-height: min-content到flexbox区域确实解决了Chrome中的问题,并且使用供应商前缀也修复了Opera和Safari,尽管Firefox仍未解决.

min-height: -moz-min-content; // not implemented
min-height: -webkit-min-content // works for opera and safari
min-height: min-content // works for chrome
Run Code Online (Sandbox Code Playgroud)

仍在寻找有关Firefox和其他潜在解决方案的想法.


col*_*r96 14

我设法用3个容器将其拉下来.诀窍是将flexbox容器与控制滚动的容器分开.最后,将所有内容放入根容器中以使其全部居中.以下是创建效果的基本样式:

CSS:

.root {
  display: flex;
  justify-content: center;
  align-items: center;
}

.scroll-container {
  margin: auto;
  max-height: 100%;
  overflow: auto;
}

.flex-container {
  display: flex;
  flex-direction: column;
  justify-content: center;
}
Run Code Online (Sandbox Code Playgroud)

HTML:

<div class="root">
  <div class="scroll-container">
    <div class="flex-container">
      <p>Lorem ipsum dolor sit amet.</p>
    </div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

我在这里创建了一个演示:https://jsfiddle.net/r5jxtgba/14/

  • 如果您从 flex-container 中删除固定高度,那么这将在演示示例中起作用,flex-container 的固定高度将不允许它占据所有累积的 flex-children 所占据的整个高度,从而达不到目的拥有一个滚动容器。 (3认同)
  • jsfiddle 显示当您在容器内添加更多内容时它不起作用。 (2认同)