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

时间:2015-10-31 17:35:22

标签: html css css3 flexbox browser-bugs

因此,在尝试使用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
}

此效果(当前)Firefox,Safari,Chrome和Opera ..如果你在IE10供应商前缀css中发表评论,它在IE10中的表现确实有趣 - 我还没有在IE11中进行测试,但假设行为匹配IE10的内容。

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

7 个答案:

答案 0 :(得分:324)

问题

Flexbox使对中非常容易。

只需将align-items: centerjustify-content: center应用于弹性容器,您的弹性项目将垂直和水平居中。

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

如问题中所述,当柔性物品溢出容器时,顶部变得无法进入。

enter image description here

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

以下是LTR容器中包含justify-content: center和三个弹性项目的示例:

enter image description here

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

解决方案#1

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

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

所以在flex容器上代替这个代码:

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

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

.flex-item {
    margin: auto;
}

enter image description here

Revised Demo

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

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

justify-content: safe center

align-self: safe center

来自CSS Box Alignment Module specification

  

4.4. Overflow Alignment: the safe and unsafe keywords and scroll safety limits

     

当[flex item]大于[flex容器]时,它会   溢出。一些对齐模式,如果在这种情况下得到尊重,可以   导致数据丢失:例如,如果侧边栏的内容是   居中,当他们溢出时,他们可能会将部分箱子送过去   视口的起始边缘,无法滚动到。

     

要控制这种情况,可以使用 溢出对齐 模式   明确指定。 Unsafe对齐符合指定的   溢出情况下的对齐模式,即使它导致数据丢失,   而safe对齐会更改溢出中的对齐模式   试图避免数据丢失的情况。

     

默认行为是包含对齐内的对齐主题   可滚动区域,虽然在撰写本安全功能时是   尚未实施。

     

<强> safe

     

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

     

<强> unsafe

     

无论[flex item]和[flex]的相对大小如何   容器],给定的对齐值很荣幸。

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

来自MDN的滚动限制说明:

  

Flex item considerations

     

Flexbox的对齐属性确实&#34; true&#34;中心,不像其他   CSS中的居中方法。这意味着flex项目将保留   居中,即使它们溢出了弹性容器。

     

但是,如果它们超过了它,有时会出现问题   页面的上边缘,或左边缘[...],如   你不能滚动到那个区域,即使那里有内容!

     

在将来的版本中,对齐属性将扩展为具有   a&#34;安全&#34;选项也是。

     

目前,如果这是一个问题,您可以使用边距来实现   集中精力,因为他们会在安全的环境中做出回应。方式并停止居中如果   他们溢出

     

不要使用align-属性,只需添加auto页边距即可   您想要居中的柔性物品。

     

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

     

auto页边距&#34; flex&#34;并假设剩余的空间,   当剩余空间和切换时,将flex项目居中   没有时正常对齐。

     

但是,如果您尝试替换justify-content   基于边距的多线程Flexbox中心,您可能已经不在了   幸运的是,因为你需要将边距放在第一个和最后一个弹性项目上   在每一行。除非你能提前预测哪些项目会   最终在哪一条线上,您无法可靠地使用基于保证金的中心   替换justify-content属性的主轴。

答案 1 :(得分:18)

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

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

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

b1 = request.POST['aNumber'] b2 = request.POST['bNumber'] 添加到flexbox区域确实解决了Chrome中的问题,并且使用供应商前缀也修复了Opera和Safari,但Firefox仍未解决。

min-height: min-content

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

答案 2 :(得分:13)

我设法用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/

答案 3 :(得分:4)

我想我找到了解决方案。它适用于lots of texta little text。您不需要指定任何内容的宽度,应该在IE8中工作。

.wrap1 {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.5);
  overflow-y: auto;
}
.wrap2 {
  display: table;
  width: 100%;
  height: 100%;
  text-align: center;
}
.wrap3 {
  vertical-align: middle;
  display: table-cell;
}
.wrap4 {
  margin: 10px;
}
.dialog {
  text-align: left;
  background-color: white;
  padding: 5px;
  border-radius: 3px;
  margin: auto;
  display: inline-block;
  box-shadow: 2px 2px 4px rgba(0, 0, 0, .5);
}
<div class="wrap1">
  <div class="wrap2">
    <div class="wrap3">
      <div class="wrap4">
        <div class="dialog">
          <p>Lorem ipsum dolor sit amet.</p>
        </div>
      </div>
    </div>
  </div>
</div>

答案 4 :(得分:1)

根据MDN,safe值现在可以提供给align-itemsjustify-content等属性。它描述如下:

  

如果项目的大小溢出对齐容器,则该项目将对齐,就像对齐模式为start一样。

因此,它可能如下使用。

.rule
{
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: safe center;
}

但是,目前还不清楚它有多少浏览器支持,我找不到任何使用它的例子,我自己也遇到过一些问题。在这里提到它以引起更多关注。

答案 5 :(得分:0)

我也设法使用了额外的容器

HTML

<div class="modal-container">
  <div class="modal">
    <div class="content-container">
       <div class="content">
         <p>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>  
</div>

CSS

.modal-container {
  display: flex;
  justify-content: center;
  align-items: center;
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background-color: black;
}

.modal {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #aaa;
  height: 80%;
  width: 90%;
}

.content-container {
  background-color: blue;
  max-height: 100%;
  overflow: auto;
  padding:0;
}

.content {
  display: flex;
  background-color: red;
  padding: 5px;
  width: 900px;
  height: 300px;
}

在jsfiddle中> https://jsfiddle.net/Nash171/cpf4weq5/

更改 .content 宽度/高度值,然后查看

答案 6 :(得分:0)

2具有表后备功能的Container Flex方法已通过IE8-9的测试,flex在IE10,11中有效。 编辑:编辑以确保在内容最少的情况下垂直居中,并增加了旧版支持。

问题的根源在于高度是从视口大小继承而来的,这会导致孩子溢出,正如Michael回答的那样。 https://stackoverflow.com/a/33455342/3500688

更简单的方法,并使用flex来维护弹出容器(内容)中的布局:

#popup {
position: fixed;
top: 0;
left: 0;
right: 0;
min-height: 100vh;
background-color: rgba(0,0,0,.25);
margin: auto;
overflow: auto;
height: 100%;
bottom: 0;
display: flex;
align-items: flex-start;
box-sizing:border-box;
padding:2em 20px;
}
.container {
background-color: #fff;
margin: auto;
border: 1px solid #ccc;
border-radius: 4px;
background: #fff;
/* width: 100%; */
max-width: 500px;
padding: 10px;
    /* display: flex; */
    /* flex-wrap: wrap; */
}
		<!--[if lt IE 10]>
<style>
	  #popup {
			display: table;
			width:100%;
		}
		.iewrapper {
			display: table-cell;
			vertical-align: middle;
		}
	</style>
	<![endif]-->
<div id="popup">
	<!--[if lt IE 10]>
<div class="iewrapper">
<![endif]-->
    <div class="container">
        <p class="p3">Test</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>
	<!--[if lt IE 10]>
<div class="iewrapper">
<![endif]-->
</div>