2

I'm trying to make a simple chat window where the messages are anchored to the right, and bottom of the window. I want the chat window to scroll when messages overflow out of the window.

I'm using flexbox to position the messages, and giving the window an overflow-y: auto;. For some reason that I cannot understand this does not work. If I remove the flex positioning off the window, scrolling works normally and as expected. Why is flexbox changing the scroll behavior?

Here's a very simple codepen that shows the problem: https://codepen.io/skypod/pen/OdavbR

.chat-window {
  background-color: grey;
  width: 400px;
  height: 400px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: flex-end;
  overflow-y: auto;
}

.message {
  background-color: blue;
  color: white;
  padding: 0.5rem;
  margin: 0.25rem;
}
<div class="chat-window">
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
  <div class="message">text</div>
</div>
kukkuz
  • 41,512
  • 6
  • 59
  • 95
Dale Spiteri
  • 767
  • 1
  • 9
  • 21
  • 2
    justify-content: flex-end; is causing this issue, remove or change it to flex-start, i think its due to flex-end making the container think its already at the end of its scroll so it does not need to scroll any further. – Ginger Wizard Feb 16 '19 at 16:35

1 Answers1

7

Remove justify-content: flex-end and add flex-direction: column-reverse instead of column direction. Now add a wrapper for the messages - see demo below:

.chat-window {
  background-color: grey;
  width: 400px;
  height: 400px;
  display: flex;
  flex-direction: column-reverse; /* CHANGED */
  /*justify-content: flex-end;*/
  align-items: flex-end;
  overflow-y: auto;
}

.message {
  background-color: blue;
  color: white;
  padding: 0.5rem;
  margin: 0.25rem;
}
<div class="chat-window">
  <div class="message-wrapper">
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
    <div class="message">text</div>
  <div>
</div>
kukkuz
  • 41,512
  • 6
  • 59
  • 95
  • This definitely works, but I'm so confused as to why. Wouldn't adding a wrapper to the messages stop the flexbox properties on chat-window from effecting them? Does column-reverse on the wrapper just anchor the window to the bottom of the scroll bar? Shouldn't the align-items: flex-end property not effect the individual message divs? I mean thank you, but I'm still slightly confused. – Dale Spiteri Feb 16 '19 at 16:58
  • even I was confused the first time I saw this - flexbox properties do not affect the `message` divs but it anchors them to the bottom of the *flex item* as the *flex item* ordering is *reversed* :) – kukkuz Feb 16 '19 at 17:01
  • @DaleSpiteri When adding the `message-wrapper` it becomes the flex child instead of the `message` items, and it is it that gets its flow reversed from top/bottom to bottom/top, hence will stick/start at the bottom. W/o the wrapper the `message` items will, so the wrapper is not really necessary here. – Asons Feb 16 '19 at 17:20
  • @DaleSpiteri The main difference when using a wrapper is the order of the `message` items, as with, the last item will be at the bottom and w/o it will be at the top. If you add a number to the first and last you'll see how it all behave. – Asons Feb 16 '19 at 17:24
  • @DaleSpiteri Here is an updated version of your codepen showing what I mean: https://codepen.io/anon/pen/LqXmjx – Asons Feb 16 '19 at 17:28
  • @LGSon - Ah, ok, I get why the wrapper is necessary to fix the order, and anchor the view to the bottom of the div. – Dale Spiteri Feb 16 '19 at 18:01
  • @kukkuz Ok, I'm glad I'm not the only one. I would typically expect the message divs to act as normal block elements that take up the entire width of their container since the wrapper isn't styled in any way to effect them. But are you saying that the flex properties that are placed on the message-wrapper via the chat-box are also effecting the message divs because they are the children of a flex child element? – Dale Spiteri Feb 16 '19 at 18:04
  • @DaleSpiteri what LGSon says sums it up :) anyway, we have the output to see for ourselves... – kukkuz Feb 16 '19 at 18:10
  • @DaleSpiteri No, flexbox properties has a parent-child relation, which means, in this case, that when there is a wrapper, the `message` items are standard block elements. – Asons Feb 16 '19 at 18:17
  • 1
    @LGSon It just clicked. I was getting thrown off by the widths of the messages in relation to the chat-box when I should have been considering them in relation to their wrapper. Thank you. – Dale Spiteri Feb 16 '19 at 19:21