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

新手上路,请多包涵

在尝试使用 flexbox 制作有用的模式时,我发现似乎是浏览器问题,并且想知道是否有已知的修复或解决方法——或者关于如何解决它的想法。

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

但是,当将垂直居中与滚动条结合使用时,模态框的顶部会变得无法访问,因为它开始溢出。在上面的示例中,您可以调整大小以强制溢出,这样做可以让您滚动到模态框的底部,但不能滚动到顶部(第一段被截断)。

 .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
}
 <div class="modal-container">
    <div class="modal-window">
        <div class="modal-content">
            <p class="p3">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
            <p class="p3">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
            <p class="p3">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
        </div>
    </div>
</div>

这会影响(当前的)Firefox、Safari、Chrome 和 Opera。有趣的是,如果您在 IE10 供应商前缀 CSS 中发表评论,它在 IE10 中的行为确实正确——我还没有费心在 IE11 中进行测试,但假设该行为与 IE10 的行为相匹配。

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

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

原文由 jejacks0n 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 854
2 个回答

问题

Flexbox 使居中变得非常容易。

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

但是,当 flex 项目大于 flex 容器时,此方法会出现问题。

如问题中所述,当弹性项目溢出容器时,顶部将无法访问。

在此处输入图像描述

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

这是一个 LTR 容器的例子,它有 justify-content: center 和三个弹性项目:

在此处输入图像描述

有关此行为的解释,请参阅此答案的底部。


解决方案 #1

要解决此问题,请使用 flexbox auto margins ,而不是 justify-content

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

因此,代替 flex 容器上的这段代码:

 #flex-container {
    align-items: center;
    justify-content: center;
}

在弹性项目上使用此代码:

 .flex-item {
    margin: auto;
}

在此处输入图像描述

修改后的演示


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

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

 justify-content: safe center

要么

align-self: safe center

来自 CSS Box Alignment Module 规范

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

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

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

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

safe

如果 [flex item] 的大小溢出 [flex container],[flex item] 将改为对齐,就好像对齐模式是 [ flex-start ] 一样。

unsafe

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

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


来自 MDN 的滚动限制说明:

弹性项目注意事项

与 CSS 中的其他居中方法不同,Flexbox 的对齐属性实现了“真正的”居中。这意味着弹性项目将保持居中,即使它们溢出了弹性容器。

然而,这有时会出现问题,如果它们溢出页面的顶部边缘或左侧边缘 […],因为您无法滚动到该区域,即使那里有内容!

在未来的版本中,对齐属性将被扩展为也有一个“安全”选项。

现在,如果这是一个问题,您可以改用边距来实现居中,因为它们会以“安全”的方式响应并在溢出时停止居中。

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

代替 justify- 属性,将自动边距放在弹性容器中第一个和最后一个弹性项目的外边缘。

auto 边距将“弯曲”并采用剩余空间,当有剩余空间时将弹性项目居中,否则切换为正常对齐。

但是,如果您尝试在多行 flexbox 中使用基于边距的居中替换 justify-content ,您可能就不走运了,因为您需要将边距放在第一个和最后一个 flex 项目上在每一行。除非您可以提前预测哪些项目将在哪一行结束,否则您不能可靠地在主轴上使用基于边距的居中来替换 justify-content 属性。

原文由 Michael Benjamin 发布,翻译遵循 CC BY-SA 3.0 许可协议

我只用了 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;
}

HTML:

 <div class="root">
  <div class="scroll-container">
    <div class="flex-container">
      <p>Lorem ipsum dolor sit amet.</p>
    </div>
  </div>
</div>

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

原文由 varogen 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题