简体   繁体   中英

Use justify-content: flex-end and to have vertical scrollbar

I have chat and I need to scroll all content to bottom. I want to use justify-content: flex-end and to have vertical scrollbar.

 .session-textchat { height: 320px; background: #fff; display: -webkit-flex; display: flex; -webkit-align-items: flex-end; align-items: flex-end; -webkit-justify-content: space-between; justify-content: space-between; -webkit-flex-direction: column; flex-direction: column; }.session-textchat.past-messages { width: 100%; max-width: 980px; margin: 0 auto; height: 83.92%; overflow-y: auto; padding: 30px 0 0; display: -webkit-flex; display: flex; -webkit-align-items: flex-end; align-items: flex-end; -webkit-justify-content: flex-end; justify-content: flex-end; -webkit-flex-direction: column; flex-direction: column; }.session-textchat.past-messages.receiver, .session-textchat.past-messages.sender { width: 100%; min-height: 47px; margin: 0 0 20px; display: -webkit-flex; display: flex; -webkit-flex-direction: row; flex-direction: row; }.session-textchat.past-messages.receiver.message, .session-textchat.past-messages.sender.message { position: relative; padding: 17px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; }.session-textchat.past-messages.receiver { text-align: left; -webkit-justify-content: flex-start; justify-content: flex-start; }.session-textchat.past-messages.receiver.message { background: #f4f4f4; color: #535353; }.session-textchat.past-messages.sender { text-align: right; -webkit-justify-content: flex-end; justify-content: flex-end; }.session-textchat.past-messages.sender.message { background: url('../img/rgbapng/0050ff26.png'); background: rgba(0, 80, 255, 0.15); color: #0050ff; }
 <div class="session-textchat"> <div class="past-messages"> <div class="receiver"> <span class="message"> Good afternoon David. Welcome to your appointment? How are you today. </span> </div> <div class="sender"> <span class="message"> Hello doctor. I feel terrible to be honest? </span> </div> <div class="receiver"> <span class="message"> I can see from your notes that you've been having some ear ache - can you tell me a bit more about your symptoms. </span> </div> <div class="sender"> <span class="message"> Hello doctor. I feel terrible to be honest? </span> </div> <div class="receiver"> <span class="message"> I can see from your notes that you've been having some ear ache - can you tell me a bit more about your symptoms? </span> </div> </div> </div>

Example is here .

Is it possible? Or please give me better solution.

Thanks in advance!
Srdjan

I just had to face this issue myself and, after concluding it is a bug , I came up with a workaround.

In summary, don't use justify-content: flex-end but rather put a margin-top: auto on the first child. Unlike flex-end this doesn't break the scrollbar functionality, and it bottom-aligns the contents when they're not overflowing the container.

Example based on @SrdjanDejanovic's fiddle is at https://jsfiddle.net/peter9477/4t5r0t5b/

In case the example isn't available, here's the relevant CSS:

#container {
    overflow-y: auto;
    display: flex;
    flex-flow: column nowrap;
    /* justify-content: flex-end; DO NOT USE: breaks scrolling */
}
#container > :first-child {
    margin-top: auto !important;
    /* use !important to prevent breakage from child margin settings */
}

An alternative workaround that I believe I've also used is to add an extra container for the scrollbar. Use the flex-end on the inner container and have the outer container handle the scrolling. I generally dislike workarounds that require adding dummy elements though, so I prefer my CSS-only solution above.

Probably you've already solved this, but I faced this problem too and found a solution by trial and error, so I'm going to share it.

Having parent container's display set to flex display: flex and child's items align to flex-end align-items: flex-end will prevent overflow-y: auto to work.

Instead, you can leave you can use next CSS properties for your parent container (in your case session-textchat ):

display: flex;
flex-direction: column-reverse; /* 'column' for start, 'column-reverse' for end */
overflow-y: scroll; /* or overflow-y: auto ... */

This will make your child div appear on the bottom of parent container (it will act like flex-end ) and enable vertical scroll if content height is bigger than parent container.

I made a little jsfiddle for you if this sounds confusing: https://jsfiddle.net/lbartolic/9od4nruy/3/

In jsfiddle you can see header part, content part and footer. Container has fixed height and each part takes required height to fill the container. Content part _b__content will be scrollable if its content is taller than _b__content 's height.

I hope this will help someone. Cheers.

Also There is also another Solution

Remove the justify-content and add flex: 1 1 auto; property to the first element( create an empty div )

Old

HTML

<div class="content-reversed">
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
</div>

CSS

.content-reversed {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}

New

HTML

<div class="content-reversed">
  <div class="fix"></div> //add this dummy div
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
</div>

CSS

.content-reversed {
  display: flex;
  flex-direction: column;
}
.content-reversed .fix {
   flex: 1 1 auto;
 }

It seems to be a common bug among the browsers.

You should distribute your style onto 2 containers: the outer will be scrolled, and the inner will be a flex container. Also, you need some js to keep your message list scrolled to bottom while adding new messages.

Here is an example of code:

markup :

<div id='outer'>
    <div id='inner-scroll'>
        <div id='inner-flex'>
            <div class='flex-item'>Item 1</div>
            <div class='flex-item'>Item 2</div>
            ...
        </div>
</div>

style :

#inner-scroll {
    height: 100%;
    overflow: auto;
}

#inner-flex {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    min-height: 100%;
}

.flex-item { /*nothing*/ }

JS :

function messagePushCallback()
{
    var scrollable=document.getElementById('inner-scroll');
    scrollable.scrollTo(0, scrollable.scrollHeight-scrollable.clientHeight);
}

// for an example
chat.onMessagePush(messagePushCallback);

window.addEventListener('load', messagePushCallback);

In JS, scrollable.scrollHeight shows the whole height of the element, including the space beyond its visible part, while scrollable.clientHeight is for the height of the visible part.

You have to turn .session-textchat into a flex column then margin-top: auto on .past-messages to send it to the bottom. Then play with overflow-y: scroll and some jQuery:

 function updateScroll() { $("#chat").animate({ scrollTop: $('#chat').prop("scrollHeight")}, 1000); } updateScroll(); $("#send_button").on('click', updateScroll);
 .session-textchat { display: flex; flex-direction: column; height: 300px; margin-bottom: 30px; background: #fff; overflow-y: scroll; } .session-textchat .past-messages { margin-top: auto; width: 100%; max-width: 980px; } .session-textchat .past-messages .receiver, .session-textchat .past-messages .sender { width: 100%; min-height: 47px; margin: 0 0 20px 0; } .session-textchat .past-messages .receiver .message, .session-textchat .past-messages .sender .message { position: relative; padding: 15px; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } .session-textchat .past-messages .receiver { text-align: left; } .session-textchat .past-messages .receiver .message { background: #f4f4f4; color: #535353; } .session-textchat .past-messages .sender { text-align: right; } .session-textchat .past-messages .sender .message { background: url("../img/rgbapng/0050ff26.png"); background: rgba(0, 80, 255, 0.15); color: #0050ff; }
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet" /> <div class="container"> <div id="chat" class="session-textchat"> <div class="past-messages"> <div class="receiver"> <span class="message"> Good afternoon David. Welcome to your appointment! How are you today? </span> </div> <div class="sender"> <span class="message"> Hello doctor. I feel terrible to be honest. </span> </div> <div class="receiver"> <span class="message"> I can see from your notes that you've been having some ear ache - can you tell me a bit more about your symptoms? </span> </div> <div class="sender"> <span class="message"> Hello doctor. I feel terrible to be honest. </span> </div> <div class="receiver"> <span class="message"> I can see from your notes that you've been having some ear ache - can you tell me a bit more about your symptoms? </span> </div> </div> </div> <div class="form-group"> <textarea class="form-control" rows="5" id="msg"></textarea> </div> <div class="form-group text-center"> <button href="#" id="send_button" class="btn btn-success">Send message</button> </div> </div>

Look at this full-screen jsFiddle .

This solution worked for me:

display: flex;
flex-direction: row-reverse;
justify-content: flex-start;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM