Html 无法滚动到容器溢出的 flex 项目的顶部
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33454533/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can't scroll to top of flex item that is overflowing container
提问by jeHymans0n
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.
因此,在尝试使用 flexbox 制作有用的模态时,我发现似乎是浏览器问题,我想知道是否有已知的修复或解决方法 - 或有关如何解决它的想法。
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.)
我试图解决的问题有两个方面。首先,让模态窗口垂直居中,按预期工作。第二个是让模态窗口滚动——在外部滚动,所以整个模态窗口滚动,而不是其中的内容(这样你就可以有下拉菜单和其他可以扩展到模态边界之外的 UI 元素——像自定义日期选择器等)
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/
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.
这会影响(当前)Firefox、Safari、Chrome 和 Opera。如果您在 IE10 供应商前缀 css 中发表评论,它在 IE10 中的行为确实很有趣——我还没有在 IE11 中进行测试,但假设行为与 IE10 的行为相匹配.
Any ideas would be good. Links to known issues, or reasoning behind this behavior would also be useful.
任何想法都会很好。已知问题的链接或此行为背后的推理也很有用。
回答by Michael Benjamin
The Problem
问题
Flexbox makes centering very easy.
Flexbox 使居中变得非常容易。
By simply applying align-items: center
and justify-content: center
to the flex container, your flex item(s) will be vertically and horizontally centered.
通过简单地将align-items: center
和应用justify-content: center
到 flex 容器,您的 flex 项目将垂直和水平居中。
However, there is a problem with this method when the flex item is bigger than the flex container.
但是,当 flex item 大于 flex 容器时,这种方法存在问题。
As noted in the question, when the flex item overflows the container the top becomes inaccessible.
正如问题中所指出的,当 flex 项目溢出容器时,顶部变得不可访问。
For horizontal overflow, the left section becomes inaccessible (or right section, in RTL languages).
对于水平溢出,左侧部分变得不可访问(或右侧部分,在 RTL 语言中)。
Here's an example with an LTR container having justify-content: center
and three flex items:
这是一个 LTR 容器的示例,其中包含justify-content: center
三个 flex 项目:
See the bottom of this answer for an explanation of this behavior.
有关此行为的解释,请参阅此答案的底部。
Solution #1
解决方案#1
To fix this problem use flexbox auto margins, instead of justify-content
.
要解决此问题,请使用flexbox auto margins,而不是justify-content
.
With auto
margins, an overflowing flex item can be vertically and horizontally centered without losing access to any part of it.
有了auto
边距,一个溢出的 flex 项目可以垂直和水平居中,而不会失去对它的任何部分的访问。
So instead of this code on the flex container:
因此,而不是 flex 容器上的这段代码:
#flex-container {
align-items: center;
justify-content: center;
}
Use this code on the flex item:
在 flex 项上使用此代码:
.flex-item {
margin: auto;
}
Solution #2 (not yet implemented in most browsers)
解决方案#2(尚未在大多数浏览器中实现)
Add the safe
value to your keyword alignment rule, like this:
将该safe
值添加到关键字对齐规则中,如下所示:
justify-content: safe center
or
或者
align-self: safe center
From the CSS Box Alignment Module specification:
来自CSS Box Alignment Module 规范:
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 alignmentmode 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.
4.4. 溢出对齐:将
safe
与unsafe
关键字和滚动安全限制当[flex item]大于[flex container]时,会溢出。某些对齐模式,如果在这种情况下使用,可能会导致数据丢失:例如,如果侧边栏的内容居中,当它们溢出时,它们可能会将部分框发送到视口的起始边缘,无法滚动到.
为了控制这种情况,可以明确指定溢出对齐模式。
Unsafe
对齐在溢出情况下遵循指定的对齐模式,即使它会导致数据丢失,而safe
对齐在溢出情况下更改对齐模式以避免数据丢失。默认行为是在可滚动区域内包含对齐主题,但在撰写本文时,此安全功能尚未实现。
safe
如果 [flex item] 的大小溢出 [flex container],则 [flex item] 将改为对齐,就好像对齐模式为 [
flex-start
]。
unsafe
无论 [flex item] 和 [flex container] 的相对大小如何,都遵循给定的对齐值。
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.
注意:盒子对齐模块用于多个盒子布局模型,而不仅仅是 flex。所以在上面的规范摘录中,括号中的术语实际上是说“对齐主题”、“对齐容器”和“ start
”。我使用了特定于 flex 的术语来关注这个特定问题。
Explanation for scroll limitation from MDN:
来自 MDN 的滚动限制解释:
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.
与 CSS 中的其他居中方法不同,Flexbox 的对齐属性执行“真正”居中。这意味着弹性项目将保持居中,即使它们溢出弹性容器。
这有时会出现问题,但是,如果它们溢出页面的顶部边缘或左边缘 [...],因为您无法滚动到该区域,即使那里有内容!
在未来的版本中,对齐属性也将扩展为具有“安全”选项。
现在,如果这是一个问题,您可以改为使用边距来实现居中,因为它们会以“安全”的方式响应并在溢出时停止居中。
而不是使用
align-
属性,只需auto
在您希望居中的弹性项目上放置边距。而不是
justify-
属性,在 flex 容器中的第一个和最后一个 flex 项目的外边缘放置自动边距。该
auto
利润率将“灵活”,并承担剩余的空间,围绕柔性物品时,有剩余的空间,并切换到正常的排列时,没有。但是,如果您尝试
justify-content
在多行 flexbox 中替换为基于边距的居中,您可能不走运,因为您需要将边距放在每行的第一个和最后一个 flex 项上。除非您可以提前预测哪些项目将在哪条线上结束,否则您无法可靠地使用主轴上的基于边距的居中来替换该justify-content
属性。
回答by jeHymans0n
Well, as Murphy's Law would have it, the reading I did after posting this question resulted in a few results -- not completely resolved, but somewhat useful nonetheless.
好吧,正如墨菲定律所要求的那样,我在发布这个问题后所做的阅读导致了一些结果——没有完全解决,但仍然有些有用。
I played around with min-height a bit before posting, but was not aware of the intrinsic sizing constraints that are fairly new to the spec.
在发布之前,我稍微使用了 min-height,但不知道规范中相当新的内在尺寸限制。
http://caniuse.com/#feat=intrinsic-width
http://caniuse.com/#feat=intrinsic-width
Adding a min-height: min-content
to the flexbox area does resolve the issue in Chrome, and with vendor prefixes also fixes Opera and Safari, though Firefox remains unresolved.
min-height: min-content
在 flexbox 区域添加 a确实解决了 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
Still looking for ideas on Firefox, and other potential solutions.
仍在寻找有关 Firefox 和其他潜在解决方案的想法。
回答by colinbr96
I managed to pull this off with just 3 containers. The trick is to separate the flexbox container from the container that controls the scrolling. Lastly, put everything into a root container to center it all. Here are the essential styles to create the effect:
我只用 3 个容器就成功解决了这个问题。诀窍是将 flexbox 容器与控制滚动的容器分开。最后,将所有内容放入根容器中以将其全部居中。以下是创建效果的基本样式:
CSS:
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:
HTML:
<div class="root">
<div class="scroll-container">
<div class="flex-container">
<p>Lorem ipsum dolor sit amet.</p>
</div>
</div>
</div>
I've created a demo here: https://jsfiddle.net/r5jxtgba/14/
我在这里创建了一个演示:https: //jsfiddle.net/r5jxtgba/14/
回答by mpen
I think I found a solution. It works with lots of textand a little text. You don't need to specify the widths of anything, and it shouldwork in IE8.
我想我找到了解决方案。它适用于大量文本和少量文本。你不需要指定任何东西的宽度,它应该可以在 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>
回答by Chris Talman
According to MDN, the safe
value can now be provided to properties like align-items
and justify-content
. It's described as follows:
根据 MDN,该safe
值现在可以提供给像align-items
和 之类的属性justify-content
。它的描述如下:
If the size of the item overflows the alignment container, the item is instead aligned as if the alignment mode were
start
.
如果项目的大小超出了对齐容器,则项目将改为对齐,就好像对齐模式为
start
。
So, it might be used as follows.
因此,它可以按如下方式使用。
.rule
{
display: flex;
flex-direction: row;
justify-content: center;
align-items: safe center;
}
However, it's unclear how much browser support it has, I could not find any examples of its use, and I have been having some issues with it myself. Mentioning it here to draw more attention to it.
但是,目前尚不清楚它有多少浏览器支持,我找不到任何使用它的示例,而且我自己也遇到了一些问题。在这里提到它是为了引起更多的注意。
回答by Nadeesh Peiris
I also managed to do it using extra container
我还设法使用额外的容器来做到这一点
HTML
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
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;
}
in jsfiddle > https://jsfiddle.net/Nash171/cpf4weq5/
在 jsfiddle > https://jsfiddle.net/Nash171/cpf4weq5/
change .contentwidth/height values and see
更改.content宽度/高度值并查看
回答by Silverandrew
2 Container Flex Method with Table fallback tested IE8-9, flex works in IE10,11. Edit: Edited to ensure vertical centering when minimal content, added legacy support.
2 带有表回退测试的容器 Flex 方法在 IE8-9 中进行了测试,flex 在 IE10,11 中有效。编辑:编辑以确保在内容最少时垂直居中,添加了旧版支持。
The issue stems from height being inherited from the viewport size which causes children to overflow, as Michael answered. https://stackoverflow.com/a/33455342/3500688
正如迈克尔回答的那样,问题源于从视口大小继承的高度,这会导致孩子溢出。https://stackoverflow.com/a/33455342/3500688
something more simple and use flex to maintain the layout within the popup container(content):
更简单的事情并使用 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>