【问题标题】:Use justify-content: flex-end and to have vertical scrollbar使用 justify-content: flex-end 并拥有垂直滚动条
【发布时间】:2016-07-07 22:41:24
【问题描述】:

我有聊天,我需要将所有内容滚动到底部。 我想使用 justify-content: flex-end 并拥有垂直滚动条。

.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>

例如here

有可能吗? 或者请给我更好的解决方案。

提前致谢!
斯尔詹

【问题讨论】:

  • 您需要能够滚动到底部或始终让内容滚动到底部?
  • 为你的父容器使用 display: flex;弹性方向:列反向;溢出-y:自动;并从您的子容器中删除 flex-end。
  • 请查看my answer
  • @Ibartolic 的回答效果很好而且很简单。

标签: css flexbox


【解决方案1】:

您必须将.session-textchat 变成一个弹性列,然后将margin-top: auto .past-messages 上的margin-top: auto 发送到底部。然后玩 overflow-y: scroll 和一些 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>

看看这个全屏jsFiddle

【讨论】:

    【解决方案2】:

    还有另一种解决方案

    删除justify-content并将flex: 1 1 auto;属性添加到第一个元素(create an empty div

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

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

    【讨论】:

      【解决方案3】:

      我不得不自己面对这个问题,在结束 it isbug 之后,我想出了一个解决方法。

      总之,不要使用justify-content: flex-end,而是将margin-top: auto 放在第一个孩子身上。与 flex-end 不同,这不会破坏滚动条的功能,并且当内容没有溢出容器时它会底部对齐。

      基于@SrdjanDejanovic 小提琴的示例位于https://jsfiddle.net/peter9477/4t5r0t5b/

      如果示例不可用,这里是相关的 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 */
      }
      

      我相信我也使用过的另一种解决方法是为滚动条添加一个额外的容器。在内部容器上使用 flex-end 并让外部容器处理滚动。不过,我通常不喜欢需要添加虚拟元素的解决方法,因此我更喜欢上面的纯 CSS 解决方案。

      【讨论】:

      • 刚刚注意到这是我的答案的副本。有什么区别?
      • @lbartolic 副本?不是真的……事实上,他们之间似乎没有什么共同之处。在发布我的之前,我当然没有读过你的文章(我不是这样写的),我的文章包含一些你没有的背景链接(经过广泛研究收集,我可能会补充),以及可能对我至关重要的页边空白部分答案不在您的手中,因此它们的某些小部分可能相同,但显然不是。
      • 我认为 'maring-top: auto' 是一个很好的方法,但是直到我们达到顶部没有空间的高度为止,所以自动边距没有帮助,例如滚动开始出现。我必须使用 scrollTop = scrollHeight 应用手动滚动来实现始终滚动的底部位置。
      • 这个解决方案甚至适用于臭名昭著的FireFox bugflexbugs。因此,出于某种神秘原因,使用flex-flowmargin-top 代替flex-direction 是可行的。
      • !important 不是反模式吗?不借助它就不能解决问题吗?没有仔细阅读,但是这个答案中的 jsfiddle 似乎不再起作用了,滚动从 Chromium 94 的顶部开始。
      【解决方案4】:

      这似乎是浏览器中的常见错误。

      您应该将您的样式分配到 2 个容器上:外部将被滚动,内部将是一个 flex 容器。此外,您需要一些 js 来让您的消息列表在添加新消息时滚动到底部。

      下面是代码示例:

      标记

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

      风格

      #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);
      

      在 JS 中,scrollable.scrollHeight 表示元素的整个高度,包括其可见部分之外的空间,而scrollable.clientHeight 表示可见部分的高度。

      【讨论】:

      • 此解决方案适用于 Firefox 57 和 Chrome 63。当前最受好评的答案(使用 column-reverse 而不是 flex-end)似乎不适用于 Firefox。
      【解决方案5】:

      可能你已经解决了这个问题,但是我也遇到了这个问题,并且通过反复试验找到了解决方案,所以我将分享它。

      将父容器的显示设置为 flex display: flex 并且子项目与 flex-end align-items: flex-end 对齐将阻止 overflow-y: auto 工作。

      相反,您可以为父容器使用下一个 CSS 属性(在您的情况下为 session-textchat):

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

      这将使您的子 div 出现在父容器的底部(其作用类似于 flex-end)并在内容高度大于父容器时启用垂直滚动。

      如果这听起来令人困惑,我为你做了一个小 jsfiddle: https://jsfiddle.net/lbartolic/9od4nruy/3/

      在 jsfiddle 中,您可以看到页眉部分、内容部分和页脚。容器具有固定高度,每个部分都需要填充容器所需的高度。如果内容部分_b__content 的内容高于_b__content 的高度,则内容部分将是可滚动的。

      我希望这会对某人有所帮助。 干杯。

      【讨论】:

      • 最后,唯一正确的答案,没有说这是一个错误。您没有解决发送者/接收者对齐问题,这可以通过每个类上的简单属性 align-self 来解决。
      • 是的,你是对的。我专注于对齐主容器(页眉/内容/页脚)。
      • jsfiddle 不适用于 Safari 9.1.1。滚动条不显示。
      • jsfiddle 在 Firefox 50.0.2 中也失败了 - 滚动条出现了,但它是灰色的。
      • 这似乎只适用于 Chrome 和 Safari (11.0),但不适用于 Firefox 和 IE。
      猜你喜欢
      • 2017-06-11
      • 2022-01-26
      • 1970-01-01
      • 2013-12-06
      • 2022-01-15
      • 2017-08-14
      • 2010-11-29
      • 2015-12-13
      • 2019-02-23
      相关资源
      最近更新 更多