无法滚动到溢出容器的弹性项目的顶部
因此,在尝试使用 flexbox 制作有用的模式时,我发现了似乎是浏览器问题,我想知道是否有已知的修复或解决方法——或者关于如何解决它的想法.
我要解决的问题有两个方面.首先,使模态窗口垂直居中,这可以按预期工作.第二个是让模态窗口滚动——在外部滚动,所以整个模态窗口滚动,而不是其中的内容(这样你就可以有下拉菜单和其他可以扩展到模态边界之外的 UI 元素——例如自定义日期选择器等)
但是,当将垂直居中与滚动条结合使用时,模式的顶部可能会因为它开始溢出而变得不可访问.在上面的示例中,您可以调整大小以强制溢出,这样做可以让您滚动到模式的底部,但不能滚动到顶部(第一段被切断).
这是示例代码的链接(高度简化)
对于水平溢出,左侧部分变得不可访问(或右侧部分,在 RTL 语言中).
这是一个具有 justify-content: center
和三个弹性项目的 LTR 容器的示例:
有关此行为的说明,请参阅此答案的底部.
<小时>解决方案 #1
要解决此问题,请使用
修改后的演示
<小时>解决方案 #2(尚未在大多数浏览器中实现)
将 safe
值添加到您的关键字对齐规则中,如下所示:
justify-content: 安全中心
或
align-self: 安全中心
来自 CSS 框对齐模块规范:
<块引用>4.4.溢出对齐:safe
和 unsafe
关键字和滚动安全限制
当 [flex item] 大于 [flex container] 时,它会溢出.某些对齐模式,如果在这种情况下得到尊重,可能导致数据丢失:例如,如果侧边栏的内容是居中,当它们溢出时,它们可能会将部分盒子送过去视口的起始边缘,不能滚动到.
为了控制这种情况,溢出对齐模式可以是明确规定.Unsafe
对齐遵循指定的溢出情况下的对齐模式,即使导致数据丢失,while safe
对齐方式在溢出时改变对齐方式避免数据丢失的情况.
默认行为是将对齐主题包含在可滚动区域,尽管在编写此安全功能时尚未实施.
安全
如果 [flex item] 的大小超出了 [flex container],则[flex item] 像对齐模式一样对齐[flex-start
].
不安全
无论 [flex item] 和 [flex item] 的相对大小如何container],给定的对齐值被尊重.
注意:Box Alignment Module 可用于多个盒子布局模型,而不仅仅是 flex.因此,在上面的规范摘录中,括号中的术语实际上是对齐主题"、对齐容器"和start
".我使用了特定于 flex 的术语来保持对这个特定问题的关注.
来自 MDN 的滚动限制说明:
<块引用>弹性项目考虑因素
Flexbox 的对齐属性做真正的"居中,不像其他的CSS中的居中方法.这意味着弹性项目将保留居中,即使它们溢出 flex 容器.
但是,如果它们溢出超出页面的上边缘或左边缘 [...],如即使那里有内容,您也无法滚动到该区域!
在未来的版本中,对齐属性将扩展为也是一个安全"选项.
目前,如果这是一个问题,您可以改为使用边距来实现居中,因为他们会以安全"的方式做出反应,如果出现以下情况则停止居中他们溢出.
不使用 align-
属性,只需将 auto
边距放在您希望居中的弹性项目.
代替 justify-
属性,将自动边距放在外面flex 容器中第一个和最后一个 flex 项的边缘.
auto
边距将弯曲"并占据剩余空间,当有剩余空间时将弹性项目居中,并切换不是时正常对齐.
但是,如果您尝试将 justify-content
替换为在多行 flexbox 中基于边距居中,你可能已经不在了运气,因为您需要将边距放在第一个和最后一个弹性项目上在每一行.除非你能提前预测哪些项目会最终在哪条线上,你不能可靠地使用基于边距的居中替换 justify-content
属性的主轴.
So, in attempting to make a useful modal using flexbox, I found what seems to be a browser issue and am wondering if there is a known fix or workaround -- or ideas on how to resolve it.
The thing I'm trying to solve, has two aspects. First, getting the modal window vertically centered, which works as expected. The second is to get the modal window to scroll -- externally, so the whole modal window scrolls, not the contents within it (this is so you can have dropdowns and other UI elements that can extend outside of the bounds of the modal -- like a custom date picker, etc.)
However, when combining the vertical centering with scroll bars, the top of the modal can become inaccessible as it begins to overflow. In the above example, you can resize to force the overflow, and in doing so it allows you to scroll to the bottom of the modal, but not to the top (first paragraph is cut off).
Here's the link to the example code (highly simplified)
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
}
This effects (current) Firefox, Safari, Chrome, and Opera.. It does interestingly behave correctly in IE10 if you comment in the IE10 vender prefixed css -- I did not bother testing in IE11 yet, but assume the behavior matches that of IE10.
Any ideas would be good. Links to known issues, or reasoning behind this behavior would also be useful.
解决方案The Problem
Flexbox makes centering very easy.
By simply applying align-items: center
and justify-content: center
to the flex container, your flex item(s) will be vertically and horizontally centered.
However, there is a problem with this method when the flex item is bigger than the flex container.
As noted in the question, when the flex item overflows the container the top becomes inaccessible.
For horizontal overflow, the left section becomes inaccessible (or right section, in RTL languages).
Here's an example with an LTR container having justify-content: center
and three flex items:
See the bottom of this answer for an explanation of this behavior.
Solution #1
To fix this problem use flexbox auto margins, instead of justify-content
.
With auto
margins, an overflowing flex item can be vertically and horizontally centered without losing access to any part of it.
So instead of this code on the flex container:
#flex-container {
align-items: center;
justify-content: center;
}
Use this code on the flex item:
.flex-item {
margin: auto;
}
Revised Demo
Solution #2 (not yet implemented in most browsers)
Add the safe
value to your keyword alignment rule, like this:
justify-content: safe center
or
align-self: safe center
From the CSS Box Alignment Module specification:
4.4. Overflow Alignment: the
safe
andunsafe
keywords and scroll safety limitsWhen the [flex item] is larger than the [flex container], it will overflow. Some alignment modes, if honored in this situation, may cause data loss: for example, if the contents of a sidebar are centered, when they overflow they may send part of their boxes past the viewport’s start edge, which can’t be scrolled to.
To control this situation, an overflow alignment mode can be explicitly specified.
Unsafe
alignment honors the specified alignment mode in overflow situations, even if it causes data loss, whilesafe
alignment changes the alignment mode in overflow situations in an attempt to avoid data loss.The default behavior is to contain the alignment subject within the scrollable area, though at the time of writing this safety feature is not yet implemented.
safe
If the size of the [flex item] overflows the [flex container], the [flex item] is instead aligned as if the alignment mode were [
flex-start
].
unsafe
Regardless of the relative sizes of the [flex item] and [flex container], the given alignment value is honored.
Note: The Box Alignment Module is for use across multiple box layout models, not just flex. So in the spec excerpt above, the terms in brackets actually say "alignment subject", "alignment container" and "start
". I used flex-specific terms to keep the focus on this particular problem.
Explanation for scroll limitation from MDN:
Flex item considerations
Flexbox's alignment properties do "true" centering, unlike other centering methods in CSS. This means that the flex items will stay centered, even if they overflow the flex container.
This can sometimes be problematic, however, if they overflow past the top edge of the page, or the left edge [...], as you can't scroll to that area, even if there is content there!
In a future release, the alignment properties will be extended to have a "safe" option as well.
For now, if this is a concern, you can instead use margins to achieve centering, as they'll respond in a "safe" way and stop centering if they overflow.
Instead of using the
align-
properties, just putauto
margins on the flex items you wish to center.Instead of the
justify-
properties, put auto margins on the outside edges of the first and last flex items in the flex container.The
auto
margins will "flex" and assume the leftover space, centering the flex items when there is leftover space, and switching to normal alignment when not.However, if you're trying to replace
justify-content
with margin-based centering in a multi-line flexbox, you're probably out of luck, as you need to put the margins on the first and last flex item on each line. Unless you can predict ahead of time which items will end up on which line, you can't reliably use margin-based centering in the main axis to replace thejustify-content
property.
相关文章