因此,在尝试使用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
}
这影响(当前)火狐,Safari,Chrome和Opera。 有趣的是,如果您在IE10供应商前缀的css中进行评论,它在IE10中的行为是正确的--我还没有费心在IE11中进行测试,但假设它的行为与IE10的行为相匹配。
任何想法都是好主意。 指向已知问题的链接,或此行为背后的推理也将是有用的。
Flexbox使对中变得非常容易。
通过简单地将align-items:center
和justify-content:center
应用到flex容器,您的flex项将垂直和水平居中。
但是,当flex项大于flex容器时,这种方法会出现问题。
正如问题中所指出的,当flex项目溢出容器时,容器顶部将变得不可访问。
对于水平溢出,左部分变得不可访问(或右部分,在RTL语言中)。
下面是一个LTR容器的示例,该容器具有justify-content:center
和三个flex项:
有关此行为的解释,请参见本答案的底部。
若要解决此问题,请使用flexbox自动边距,而不是justify-content
。
使用自动
边距,溢出的flex项可以垂直和水平居中,而不会失去对其任何部分的访问。
所以代替flex容器上的这段代码:
#flex-container {
align-items: center;
justify-content: center;
}
在flex项上使用以下代码:
.flex-item {
margin: auto;
}
修订演示
将safe
值添加到关键字对齐规则中,如下所示:
justify-content: safe center
或
align-self: safe center
来自CSS框对齐模块规范:
4.4. 溢出对齐:safe
和unsafe
关键字和滚动安全限制
当“flex项目”大于“flex容器”时,它会溢出。 在这种情况下,如果采用某些对齐模式,可能会导致数据丢失:例如,如果侧边栏的内容居中,当它们溢出时,可能会将它们的部分框发送到视口的起始边缘,从而无法滚动到该边缘。
要控制这种情况,可以显式指定溢出对齐模式。 unsafe
对齐在溢出情况下遵守指定的对齐模式,即使它会导致数据丢失,而safe
对齐在溢出情况下更改对齐模式,以试图避免数据丢失。
默认的行为是将对齐主题包含在可滚动区域中,尽管在编写本文时还没有实现这个安全特性。
安全
如果[flex item]的大小溢出[flex container],则[flex item]将改为对齐,就像对齐模式是[Flex-Start
]一样。
不安全
无论[flex item]和[flex container]的相对大小如何,给定的对齐值都是有效的。
注意:Box Alignment模块适用于多个Box布局模型,而不仅仅是Flex。 所以在上面的spec摘录中,括号中的术语实际上是说“对齐主题”,“对齐容器”和“开始
”。 我使用了特定于Flex的术语来保持对这个特定问题的关注。
弹性项目注意事项
与CSS中的其他对中方法不同,FlexBox的对齐属性执行“true”居中。 这意味着flex项将保持居中,即使它们溢出了flex容器。
然而,如果它们溢出页面的上边缘或左边缘[...],这有时会有问题,因为即使那里有内容,您也无法滚动到该区域!
在未来的版本中,对齐属性将被扩展为具有“安全”选项。
现在,如果这是一个问题,您可以使用边距来实现居中,因为边距会以一种“安全”的方式做出响应,如果溢出,就会停止居中。
不使用align-
属性,只需将auto
页边距放在要居中的flex项上。
不要使用justify-
属性,而是将自动边距放置在flex容器中第一个和最后一个flex项的外部边缘上。
自动
边距将“弹性”并假定剩余空间,当有剩余空间时将弹性项居中,当没有剩余空间时切换到正常对齐。
但是,如果您试图在多行flexbox中用基于边距的居中位置替换justify-content
,那么您可能就不走运了,因为您需要在每行的第一个和最后一个flex项目上放置边距。 除非您能够提前预测哪些项目将结束在哪一行上,否则您无法可靠地使用主轴中基于边距的居中来替换justify-content
属性。
好吧,正如墨菲定律所说的,我在贴出这个问题之后的阅读,得到了一些结果--虽然没有完全解决,但还是有点用处。
在发布之前,我对min-height进行了一些尝试,但是没有意识到内部的大小约束,这对于规范来说是相当新的。
http://caniuse.com/#feate=intrinsic-width
在flexbox区域添加min-height:min-content
确实解决了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
还在寻找Firefox上的想法,以及其他潜在的解决方案。
我只用了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/