Can't scroll to top of flex item that is overflowing container
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
considerationsFlexbox'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.
scrolling flex container does not fit centered items
According to MDN (Flex item considerations), this behavior is expected for now:
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 put auto 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.
So, you can achieve then expected result, using margins for alignment. Just add margin-left: auto
for first item and margin-right:auto
for last.
My demo: http://jsfiddle.net/WFxQk/
How do I fix scrolling when flexbox content is vertically centered?
align-items: safe center
should avoid children to go off the box .
https://developer.mozilla.org/en-US/docs/Web/CSS/align-items
safe
Used alongside an alignment keyword. If the chosen keyword means that the item overflows the alignment container causing data loss, the item is instead aligned as if the alignment mode were start.
html, body {
height: 100%;
}
body {
display: flex;
flex-wrap: nowrap;
flex-direction: row;
overflow: hidden;
}
.container {
overflow-y: auto;
display: flex;
flex-wrap: nowrap;
flex-direction: row;
align-items: safe center;
}
.content {
border: 1px solid grey;
background-color: lightgrey;
padding: 10px;
margin: 10px;
border-radius: 10px;
}
<div class="container">
<div class="content">
Start of the content
<br />
<br />
Middle of the content
<br />
<br />
End of the content
</div>
</div>
<div class="container">
<div class="content">
Start of the content :(((
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Middle of the content
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
End of the content
</div>
</div>
CSS Flex overflow and center
You need a work around via pseudos to simulate justify-content:center;
when it should show:
remove : justify-content:center;
and add
&::before ,
&::after {
content:'';
flex:1;
}
.projets { display: flex; flex-direction: row; overflow: scroll;}
.projets::before,.projets::after { content: ''; flex: 1;}
.projets .projet_outter { width: 440px; height: 240px; flex-shrink: 0;}
.projets .projet { border-radius: 10px; box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.15); background-color: white; width: 400px; height: 200px; margin: 20px auto;}
.projets .projet .num { margin: 0px auto; background-color: #005FB9; border-radius: 50%; width: 40px; height: 40px; line-height: 40px; color: white; vertical-align: middle; text-align: center; transform: translateY(-50%);}
<div class="projets">
<div class="projet_outter"> <div class="projet"> <div class="num"> 1 </div> projet aez </div> </div> <div class="projet_outter"> <div class="projet"> <div class="num"> 2 </div> projet </div> </div></div><hr/>
<div class="projets">
<div class="projet_outter"> <div class="projet"> <div class="num"> 1 </div> projet aez </div> </div> <div class="projet_outter"> <div class="projet"> <div class="num"> 2 </div> projet </div> </div>
<div class="projet_outter"> <div class="projet"> <div class="num"> 3 </div> projet </div> </div> <div class="projet_outter"> <div class="projet"> <div class="num"> 4 </div> projet </div> </div> <div class="projet_outter"> <div class="projet"> <div class="num"> 5 </div> projet </div> </div> <div class="projet_outter"> <div class="projet"> <div class="num"> 6 </div> projet </div> </div> <div class="projet_outter"> <div class="projet"> <div class="num"> 7 </div> projet </div> </div>
</div>
Flex container with flex-direction column-reverse will not scroll to top
The problem was with the scrollTop
positioning. The 0 value will scroll to the bottom because of the reverse direction property. The simple trick was to set a negative value :
function scrollNotifications() {
var element = document.getElementById('scrollDiv')
element.scrollTop = -element.scrollHeight
}
Weird flex wrap positioning with vertical scroll
New CSS.
Now everything is as the author wanted, no distance between cards.
.main {
display: flex;
flex-direction: column;
/*justify-content: space-between;*/
height: 100%;
}
.cards {
display: flex;
flex-wrap: wrap;
margin: 1rem;
/*height:70vh*/
overflow-y: scroll;
}
.bottom-bar{
margin-top:auto
}
Related Topics
How to Lock Viewport to Portrait Orientation in Html5/Css3
How to Set Textarea to 100% Width and Height
How to Select All the Checkboxes in Angular 6
How to Display Dynamic Json Data in HTML Using Angular 6
How to Create an HTML Table With a Fixed/Frozen Left Column and a Scrollable Body
How to Append Querystrings to a Url on Submit of a Form
How to Use CSS to Show on Hover Tool-Tips Using the Same Text Which Is Shortend With Ellipses
Angular 2: Get Position of HTML Element
Why Align Items Center Not Working
How to Make Bootstrap 4 Cards the Same Height in Card-Columns
How to Change Bootstrap 4 Drop-Down Colors
Why Is There a White Space Between Parent Div and Inner Div in React
How to Embed Pdf File With Responsive Width
Align Left and Right in Mat-Card-Title
How to Make Space Between Two Buttons in Same Div