Use Justify-Content: Flex-End and to Have Vertical Scrollbar

flexbox won't overflow with justify-content: flex-end

You were almost there!

Two things that you can do to get you closer:

  1. To prevent the flex items from collapsing ( dividing itself among the space of the container it's placed in ) is to set an explicit min-height instead of just a height
  2. Create a container div that wraps your messages: .messages-container and give this an explicit max-height and overflow auto.

HTML:

<div class="messages">
<div class="messages-container"> <!-- New Wrapping Container -->
<div class="message user">

CSS:

    .message {
min-height: 80px;
}

.messages-container {
height: 100%;
max-height: 300px;
overflow: auto;
}
.messages{
display: flex;
flex-direction: column;
justify-content: flex-end;
overflow: auto;
}

Working Example:

.container {  width: 60%;  height: 300px;  display: flex;  flex-direction: column;  justify-content: flex-end;}
.messages-container { height: 100%; max-height: 300px; overflow: auto;}
.messages{ display: flex; flex-direction: column; justify-content: flex-end; overflow: auto;}
.message { margin: 5px; min-height: 80px; display: flex; flex-direction: row;}
.message.user { justify-content: flex-end; background-color: #2bf;}
.message.other { justify-content: flex-start; background-color: #bbb;}
.write-zone { width: 100%; height: 7%; display: flex; flex-direction: row; justify-content: space-around;}
input { width: 80%;}
<div class="container">  <div class="messages">  <div class="messages-container">    <div class="message user">      Toto    </div>    <div class="message other">      Titi    </div><div class="message user">      Toto    </div>    <div class="message other">      Titi    </div>    <div class="message user">      Toto    </div>    <div class="message other">      Titi    </div>    <div class="message user">      Toto    </div>    <div class="message other">      Titi    </div>    <div class="message user">      Toto    </div>    <div class="message other">      Titi    </div>    <div class="message user">      Toto    </div>    <div class="message other">      Titi    </div>    </div>  </div>  <div class="write-zone">    <input type="text" />    <button>    send    </button>  </div></div>

Forcing vertical scrolling on a flexbox?

You can fix that by adding a wrapper around your .discussion <section> and adding the overflow-y: scroll there or just by removing the wrap from flex-flow: column wrap, which in this example doesn't seem necessary:

body {  font-family: monospace;  margin: 0;  padding: 1em;  box-sizing: border-box;  height: 100vh;}
.wrapper { overflow-y: scroll; width: 50vw; height: 100%; margin: 0 auto; box-shadow: 0 0 32px rgba(0, 0, 0, .25); padding: 1em; box-sizing: border-box;}
.discussion { display: flex; flex-flow: column; list-style: none; margin: 0; padding: 0;}
.discussion > .bubble { border-radius: 1em; padding: 0.5em; max-width: 66.6666%; box-sizing: border-box;}
.discussion > .bubble + .bubble { margin-top: 1px;}
.discussion > .bubble.last + .bubble.first { margin-top: 0.5em;}
.discussion > .bubble.sender { align-self: flex-start; background-color: cornflowerblue; color: #fff;}
.discussion>.bubble.recipient { align-self: flex-end; background-color: #efefef;}
.discussion > .bubble.sender.first { border-bottom-left-radius: 0.1em;}
.discussion > .bubble.sender.last { border-top-left-radius: 0.1em;}
.discussion>.bubble.sender.middle { border-bottom-left-radius: 0.1em; border-top-left-radius: 0.1em;}
.discussion > .bubble.recipient.first { border-bottom-right-radius: 0.1em;}
.discussion > .bubble.recipient.last { border-top-right-radius: 0.1em;}
.discussion > .bubble.recipient.middle { border-bottom-right-radius: 0.1em; border-top-right-radius: 0.1em;}
<section class="wrapper">
<ul class="discussion"> <li class="bubble sender first">Hello</li>
<li class="bubble sender last">This is a CSS demo of the Messenger chat bubbles, that merge when stacked together.</li>
<li class="bubble recipient first">Oh that's cool!</li>
<li class="bubble recipient last">Did you use JavaScript to perform that kind of effect?</li>
<li class="bubble sender first">No, that's full CSS3!</li>
<li class="bubble sender middle">(Take a look to the 'JS' section of this Pen... it's empty! lt;/li>
<li class="bubble sender last">And it's also really lightweight!</li>
<li class="bubble recipient">Dope!</li>
<li class="bubble sender first">Yeah, but I still didn't succeed to get rid of these stupid .first and .last classes.</li>
<li class="bubble sender middle">The only solution I see is using JS, or a <div> to group elements together, but I don't want to ...</li>
<li class="bubble sender last">I think it's more transparent and easier to group .bubble elements in the same parent.</li> </ul>
</section>

Overflow auto not working with justify-content: flex-end

When an overflow occur to the left (or top), a scroll doesn't get rendered, and the reason is that a HTML document's normal flow is left-to-right (top-to-bottom).

Flexbox has a row-reverse direction, which will solve that, thought 2 things comes with that:

  • One need to reorder the items or use an inner wrapper

  • I.a. Firefox and Edge doesn't show the scroll (possible bug)

Stack snippet

.row {  width: 100%;  max-width: 500px;  background: #DADADA;  display: flex;  flex-direction: row-reverse;  overflow: auto;}.box {  width: 200px;  height: 40px;  margin: 4px 10px;  background: red;  flex-shrink: 0;}
/* no wrapper */.row > .box:nth-child(1) { order: 6; }.row > .box:nth-child(2) { order: 5; }.row > .box:nth-child(3) { order: 4; }.row > .box:nth-child(4) { order: 3; }.row > .box:nth-child(5) { order: 2; }.row > .box:nth-child(6) { order: 1; }
/* wrapper */.inner { display: flex;}
<div class="row">  <div class="box">1</div>  <div class="box">2</div>  <div class="box">3</div>  <div class="box">4</div>  <div class="box">5</div>  <div class="box">6</div></div>
<div><br><br></div>
<div class="row"> <div class="inner"> <div class="box">1</div> <div class="box">2</div> <div class="box">3</div> <div class="box">4</div> <div class="box">5</div> <div class="box">6</div> </div></div>

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>

Why does justify-content: flex-end remove scrollability from a container with overflow-x: auto?

Adding margin-left: auto on the first child may help. It right-aligns the contents when they're not overflowing without breaking the scrollbar functionality.

.horizontal-scroller {  background-color: #ccc;  display: flex;  overflow-x: auto;  width: 100%;}
button { white-space: nowrap;}
button::before { content: 'A button with a label';}.horizontal-scroller button:nth-of-type(1) { margin-left: auto;}
<div class="horizontal-scroller">  <button type="button"></button>  <button type="button"></button>  <button type="button"></button>  <button type="button"></button>  <button type="button"></button>  <button type="button"></button>  <button type="button"></button>  <button type="button"></button>  <button type="button"></button>  <button type="button"></button></div><p>Scrollable Container</p>
<div class="horizontal-scroller"> <button type="button"></button> <button type="button"></button> <button type="button"></button></div><p>Scrollable Container with no overflow</p>

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
}

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.

Sample Image

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:

Sample Image

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;
}

Sample Image

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 and unsafe keywords and
scroll safety
limits

When 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,
while safe 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 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.

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 the justify-content property.



Related Topics



Leave a reply



Submit