3

I have a layout with a content area which have it's own scrollbar since I want the sidebar to scroll independently.

The content of the content area is dynamically appended using a button at the bottom.

When the content area's scroll position is at the very top (scrollTop === 0) and I append more content the scroll position stays at the top. If however the scroll position is not at the top Firefox and Chrome behave differently. In Firefox the scroll position stays relative to the top and content is appended below, off screen if necessary. In Chrome however the scroll position stays relative to the bottom keeping the button in the same position resulting in the user having to scroll up to see the new content.

Is there a way to get Chrome to behave like Firefox do?

To clarify. I do not want the content area to scroll to the bottom after new content has been added. I want it to stay where it is so that users don't have to scroll up to see the new content.

var count = 1;

window.addEventListener('load', function() {
  var container = document.querySelector('[data-result]');
  var button = document.querySelector('button');

  button.addEventListener('click', function() {
    for (var i = 0; i < 10; i++) {
      var element = document.createElement('div');
      element.innerHTML = 'Content row ' + count++;

      container.appendChild(element);
    }
  });
});
html,
body,
.page {
  height: 100vh;
  margin: 0;
}

body {
  background-color: #eceff1;
}

.page {
  display: flex;
  flex-direction: column;
}

.header {
  padding: .5rem;
}

.view {
  display: flex;
  flex-direction: row;
  overflow-y: hidden;
}

.sidebar {
  display: inline-flex;
  flex-shrink: 0;
}

.content {
  margin-left: .5rem;
  display: flex;
  flex-grow: 1;
  margin-bottom: 2rem;
}

.scrollbar {
  overflow: auto;
  width: 100%;
  height: 100%;
}

.card {
  background-color: #fff;
}

.menu {
  white-space: nowrap;
  padding: .3rem .5rem;
}
<!doctype html>
<html lang="en">

  <head>
    <title></title>
  </head>

  <body>
    <div class="page">
      <div class="header">Header</div>
      <div class="view">
        <div class="sidebar">
          <div class="scrollbar">
            <div class="card">
              <div class="menu">Sidebar row 1</div>
              <div class="menu">Sidebar row 2</div>
              <div class="menu">Sidebar row 3</div>
              <div class="menu">Sidebar row 4</div>
              <div class="menu">Sidebar row 5</div>
              <div class="menu">Sidebar row 6</div>
              <div class="menu">Sidebar row 7</div>
            </div>
          </div>
        </div>
        <div class="content">
          <div class="scrollbar">
            <div data-result></div>
            <div>
              <button>
                Show more
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </body>

</html>
opex
  • 234
  • 2
  • 6
  • If you want it to always show the element scrolled to the very bottom after you inserted new elements, then just _force_ that via script as well. – CBroe Sep 10 '20 at 08:56
  • Does this answer your question? [Scroll to bottom of div?](https://stackoverflow.com/questions/270612/scroll-to-bottom-of-div) – CBroe Sep 10 '20 at 08:57
  • As usual reality is much more complex than the code snippet. The reality being a modular React app where the scroller is nowhere near the content being dynamically loaded. But if the only way is keeping a reference to the scroll position before and after content has been added and restore the previous value. I guess I'll go down that rabbit hole. I was only hoping for something more elegant to counter, in my opinion, the weird behavior of Chrome. – opex Sep 10 '20 at 09:09

2 Answers2

6

I had a similar issue, and found this (https://github.com/angular-ui/ui-scroll/issues/138). I had to put overflow-anchor:none; on a parent element to stop Chrome's behaviour. In your case, I got it to work by adding this style to .scrollbar

Note: this css is not compatible with IE or Safari, but this issue doesn't happen on Safari, and no one cares about IE anymore.. :)

Dharman
  • 30,962
  • 25
  • 85
  • 135
whywhychoi
  • 61
  • 3
1

My current solution is to save the scrollTop of the scrollable div before more content is added and restore that value if it changed after content was added. This will make Chrome behave more or less like Firefox.

Unfortunately it's not a perfect solution since there is a quick flicker to the content in Chrome since it scrolls to the bottom and than back.

opex
  • 234
  • 2
  • 6