3

I'm stuck at some point. I'm trying to do a three-column page layout. The Middle section is for posts, the right section is for some other links and references and so (A bit long). Left is fixed.

My question is; How can I stop the right div from moving when it reaches its bottom? And if the middle div's content is shorter then the right also has a scrollbar for the page for the right div. Just like Twitter does.

I tried to do some brainstorming. And thought maybe Twitter makes double divs for those sections. One is normal, the other is the fixed bottom it. So normal one stretches the page for scrolling, and the other one sticks on top of it. But I'm not sure if I'm right.

Or is it possible with pure CSS? (Also I'm using TailwindCSS)

Anyway; here is a presentation of my thought. (Or you can simply look at twitter homepage feed)

enter image description here

enter image description here

Also here is a gif;

click

Aniket Das
  • 367
  • 1
  • 6
  • 17
I. Kaya
  • 89
  • 8
  • Did you ever find the solution? – swift nub Jun 22 '23 at 21:03
  • 1
    @swiftnub Looking at the Twitter website with Developer Tools open, I see that the declarations for `margin-top`, `top`, and `bottom` are changed as I scroll. I assume this involves JavaScript. – Tim R Jun 23 '23 at 02:39

5 Answers5

3

I think this is what you are looking for. It's a two parter:

1. Flexbox and position:sticky

The trick lies in using flexbox layout, and setting both position:sticky, and setting an align-self property based on the scrolling direction. This requires step 2: Javascript.

2. JavaScript on scroll to set margin, position and align-self

The JavaScript detects a change in scrolling direction, and if it has changed, it:

  1. Sets align-self to flex-end when scrolling up, or flex-start when scrolling down.
  2. Sets bottom (when scrolling up) or top (when scrolling down) to the result of the calculation window height - sidebar height. This is basically the amount of sidebar pixels that are currently off-screen.
  3. Calculates the current 'space left' on either the top (when scrolling down) or the bottom (when scrolling up) and sets it as a top or bottom margin, so the sidebar stays in the position it was in, visually.

Setting the margins facilitates the sidebar scrolling up again immediately as the user begins scrolling up, instead of the user having to scroll all the way back up again to 'un-trigger' the sticky position.

Demo

See the demo below, on Codepen, or at my own site here.

EDIT: As pointed out by damzaky my solution did not take into account that the sidebar needs to begin scrolling up as soon as the user scrolls back up again, so I wrote and added the JavaScript part.

EDIT 2: I completely rewrote the JavaScript and it now works much better (as far as I can tell)

//select sidebar
const sidebar = document.querySelector('.sidebar');

//define handler as self-invoking so it runs on load. This takes into account he user has refreshed the page,
//and is starting from an already scrolled-down position
const handleSidebar = (function() {

  //create a states object for storing states
  const states = {};

  return function() {
    //determine scrolling direction
    let isScrollingUp = (states.prevY || window.scrollY) > window.scrollY;

    //check if scrolling direction has actually changed
    if (states.prevState !== isScrollingUp) {

      const windowHeight = window.innerHeight; //alternatively, use document.body.clientHeight here.
      const sidebarHeight = sidebar.scrollHeight;
      const sidebarTopSpace = sidebar.offsetTop;
      const sidebarBottomSpace = sidebar.parentElement.scrollHeight - (sidebarHeight + sidebarTopSpace);

      if (windowHeight > sidebarHeight) {
        //if the sidebar is shorter than the window height, just fix it to the top
        sidebar.style.top = 0;
        sidebar.style.alignSelf = 'flex-start';
      } else {
        if (isScrollingUp) {
          sidebar.style.bottom = (windowHeight - sidebarHeight) + "px";
          sidebar.style.marginBottom = sidebarBottomSpace + "px";
          sidebar.style.alignSelf = 'flex-end';
          //unset top and margin-top
          sidebar.style.top = sidebar.style.marginTop = "";
        } else {
          sidebar.style.top = (windowHeight - sidebarHeight) + "px";
          sidebar.style.marginTop = sidebarTopSpace + "px";
          sidebar.style.alignSelf = 'flex-start';
          //unset bottom and margin-bottom
          sidebar.style.bottom = sidebar.style.marginBottom = "";
        }
      }

    }

    //store scroll position and scrolling direction for next call
    states.prevY = window.scrollY;
    states.prevState = isScrollingUp;
  }
})();

//bind to scroll
window.addEventListener('scroll', handleSidebar);
div {
  display: flex;
  border: 1px solid red;
}

div.wrapper {
  position: relative;
  flex-direction: row;
}

div.wrapper .scroller {
  width: 80%;
  overflow-y: visible;
  flex-direction: column;
}

div.wrapper .sidebar {
  position: sticky;
  width: 20%;
  flex-direction: column;
  flex-grow: 0;
  align-self: flex-start;
  height: fit-content;
}
<div class="wrapper">
  <div class="scroller">
    <h2>Main scroller</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>
  </div>
  <div class="sidebar">
    <h2>Sidebar content</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a mattis augue. Aliquam mattis est at consequat molestie. Maecenas suscipit orci turpis, ut porttitor velit posuere ac. Integer tellus diam, condimentum ac tellus vitae, fermentum dapibus
      nisl. Nulla euismod pharetra maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris ut augue mi. Integer nec rhoncus lectus, sed ullamcorper tellus. Pellentesque ultrices rutrum mauris, quis sagittis
      metus dapibus vel. Donec at enim nunc. Praesent egestas luctus justo, sed consequat neque auctor vel. Mauris non volutpat ipsum. Sed id ligula quis nisl blandit auctor. Fusce lobortis consectetur ullamcorper.</p>

  </div>
</div>
Klaas Leussink
  • 2,208
  • 16
  • 23
  • this is a good CSS only solution, the only problem is that once it has scrolled past the sidebar (e.g. reaching the bottom of the middle section), user has to scroll all the way up to see the top section of the sidebar. But whether this is a problem or not depends on OP or the bounty starter, i'm just pointing out – Damzaky Jun 23 '23 at 09:53
  • Fair point. I've managed to do it, though it does require some JavaScript, I'll update my answer in a few minutes – Klaas Leussink Jun 23 '23 at 11:41
  • 1
    done. I think now it should be exactly what the OP wants. Thanks for your feedback, Damzaky! – Klaas Leussink Jun 23 '23 at 12:09
  • Scroll to the bottom of the sidebar, scroll up a bit, and then start scrolling down again. The sidebar jumps back to the bottom. Similar effect in the other direction. – Darryl Noakes Jun 23 '23 at 21:26
  • 1
    Noticed that too. Have been breaking my head about this whole thing yesterday, and plan to rework it in the coming week – Klaas Leussink Jun 24 '23 at 12:25
  • Reworked the JavaScript logic, and now it seems to run perfectly – Klaas Leussink Jun 26 '23 at 08:07
3

The other solutions here has some jank to it. This has to be done through attaching an event on window scroll.

The exact answer you are looking for is a "scrolling sticky sidebar". A clean implementation with minimal code is located here.

Pasting the relevant parts here:

First:

create a sidebar container with and sub container wrapper

<div class="sidebar">
  <div class="content-wrapper">
    <!-- content -->
    <div></div>
    <div></div>
    <div></div>
    <div></div>
  </div>
</div>

Second:

Get the components and check for scrollpositions before setting the values if at the end

let sidebar = document.getElementsByClassName("sidebar")[0];
let sidebar_content = document.getElementsByClassName("content-wrapper")[0];

window.onscroll = () => {
        let scrollTop = window.scrollY; // current scroll position
        let viewportHeight = window.innerHeight; //viewport height
        let contentHeight = sidebar_content.getBoundingClientRect().height; // current content height
        let sidebarTop = sidebar.getBoundingClientRect().top + window.pageYOffset; //distance from top to sidebar
}

if(scrollTop >= contentHeight - viewportHeight + sidebarTop) {
  sidebar_content.style.transform = `translateY(-${contentHeight - viewportHeight + sidebarTop}px)`;
  sidebar_content.style.position = "fixed";
}
else {
  sidebar_content.style.transform = "";
  sidebar_content.style.position = "";
}

Result:

enter image description here

Read up on the link above as it has more details.

Just a coder
  • 15,480
  • 16
  • 85
  • 138
2

I think you can use a js library called sticky-sidebar for this.

var sidebar = new StickySidebar('#sidebar', {
  containerSelector: '#main',
  innerWrapperSelector: '.sidebar__inner',
});
body {
  background: #3f87c2;
  margin: 0;
  padding: 0;
  text-align: center;
}

#main {
  display: flex;
}

#middle {
  flex-grow: 1;
  background: #4dd2ff;
}

#sidebar {
  min-height: 1000px;
  width: 200px;
  background: #4dd2ff;
  margin-left: 15px;
}

.sidebar {
  will-change: min-height;
}

.sidebar__inner {
  transform: translate(0, 0);
  /* For browsers don't support translate3d. */
  transform: translate3d(0, 0, 0);
  will-change: position, transform;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/sticky-sidebar/3.3.1/sticky-sidebar.min.js" integrity="sha512-iVhJqV0j477IrAkkzsn/tVJWXYsEqAj4PSS7AG+z1F7eD6uLKQxYBg09x13viaJ1Z5yYhlpyx0zLAUUErdHM6A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div id="main">
  <div id="middle">
    <div>Middle Div Content (Sooo long)</div>
    <div style="margin-top: 2400px">End of Middle Content</div>
  </div>
  <div id="sidebar" class="sidebar">
    <div class="sidebar__inner">
      <div>Right Div Content</div>
      <div style="margin-top: 900px">Right Div Content Bottom</div>
    </div>
  </div>
</div>

Maybe it's possible to make something like this from scratch, but this library handles all the backward compatibility and also the performance, so I think it's a good library. The full documentation is here.

Damzaky
  • 6,073
  • 2
  • 11
  • 16
0

You can use the following CSS code in the element which needs to stop position: sticky; bottom: 0

Refer to the following post on Stackoverflow for more information How does the "position: sticky;" property work?

Hope this answers your question!

Edit: [Try this out]

.main {
  width: 100%;
  height: 1000px;
  display: flex;
}

.first {
  width: 30%;
  background-color: red;
}

.second {
  width: 40%;
  background-color: green;
}

.third {
  width: 30%;
  background-color: blue;
  height: 500px;
  position: sticky; 
  top: 0px;
}

p {
  margin-left: 20px;
}
<div class="main">
  <div class="first">
    <p>
      Left content.
    </p>
  </div>

  <div class="second">
    <p>
      Main content.
    </p>
  </div>
  <div class="third">
    <p>
      Right content.
    </p>
  </div>
</div>
  • Should I create another div for sticky? Because I'm using flexbox for layout. Like this: https://jsfiddle.net/XpDeviL/sqh7mw8n/1/ – I. Kaya Jan 04 '21 at 11:47
  • 1
    This is not exactly what I want. With this, you shoud scroll to end of the page to see the bottom of the third div. I want something just like this: [link](https://imgur.com/eljA2Bo) – I. Kaya Jan 05 '21 at 18:01
0

I looked up twitter HTML and css using dev tools and I think that's how they implement them, I created similar implementation with three vertical sections, the right and middle section are contained on a parent div just like twitter implementation (so the scrollbar in twitter is that of the parent div of the middle and right section, it's of either the middle or the right sections, otherwise the scrollbar position would be on the middle section right edge). Try scrolling the middle section to see the result (scrollbars are hidden).

Notes:

  • The passive: true option in the scrollbar event is for better browser performance for scroll event, since scroll events are heavy performance-wise.

  • If your right section don't have much content same as twitter and there's small amount of scrolling in them, you may better try using IntersectionObserver like the last section in this CSS Tricks article for better performance (as scroll event will be triggering event after right section has reached its bottom and scroll events are heavy on performance). You will scroll all the way to the bottom after crossing your observer line on scrolling down, and all the way to the top after scrolling your observer on scrolling up, using similar code to this snippet

    right.scrollTo({
        top: right.scrollHeight,
        behavior: "smooth",
    });
    

You can may look up this answer where I use IntersectionObserver to show up button (the observer is the red line guide in this answer, in the implementation it will be hidden)

Feel free to ask in the comments if anything is unclear.

const content = document.querySelector('.content-container');
const right = document.querySelector('.right');

const scrollSpeed = 1;

console.log(right);

content.addEventListener("scroll", (e) => {
  console.log(content.scrollTop);
  right.scrollTop = content.scrollTop * scrollSpeed;
}, {
  passive: true
})
body {
  margin: 0;
  padding: 0;
}

.main {
  display: flex;
  height: 100vh;
  overflow-y: hidden;
}

.middle {
  flex: 1;
  height: auto;
}

.left,
.right {
  width: 150px;
  max-height: 100vh;
  overflow-y: auto;
}

.left {
  background: gray;
}

.left,
.middle,
.right {
  padding: 1rem;
}

.right {
  background: lightgray;
  position: sticky;
  top: 0;
  overflow-y: auto;
  padding: 0;
  padding: 1rem;
}

.content-container {
  flex: 1;
  display: flex;
  position: relative;
  overflow-y: auto;
  z-index: 0;
  background: whitesmoke;
}

.right::-webkit-scrollbar,
.left::-webkit-scrollbar,
.content-container::-webkit-scrollbar {
  display: none;
}

.right,
.left,
.content-container {
  -ms-overflow-style: none;
  /* Internet Explorer 10+ */
  scrollbar-width: none;
  /* Firefox */
}


/* helper classes to overflow containers */

.menu {
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  list-style: none;
  font-size: 1.1rem;
}

.middle-section-content {
  display: flex;
  flex-direction: column;
  gap: 2.5rem;
}

.middle-section-content div {
  min-height: 150px;
}
<div class="main">
  <div class="left">
    <h2>
      First
    </h2>
    <ul class="menu">
      <li>
        Menu Item
      </li>
      <li>
        Menu Item
      </li>
      <li>
        Menu Item
      </li>
      <li>
        Menu Item
      </li>
      <li>
        Menu Item
      </li>
      <li>
        Menu Item
      </li>
      <li>
        Menu Item
      </li>
      <li>
        Menu Item
      </li>
      <li>
        Menu Item
      </li>
      <li>
        Menu Item
      </li>
      <li>
        Menu Item
      </li>
      <li>
        Menu Item
      </li>
      <li>
        Menu Item
      </li>
      <li>
        Menu Item
      </li>
      <li>
        Menu Item
      </li>
      <li>
        Menu Item
      </li>
      <li>
        Menu Item
      </li>
      <li>
        Menu Item
      </li>
      <li>
        Menu Item
      </li>
      <li>
        Menu Item
      </li>
    </ul>
    <div>
      End of Left Section
    </div>
  </div>
  <div class="content-container">
    <div></div>
    <div class="middle">
      <h2>
        Middle Section
      </h2>

      <div class="middle-section-content">

        <div>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</div>
        <div>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</div>
        <div>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</div>
        <div>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</div>
        <div>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</div>
        <div>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</div>
        <div>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</div>

      </div>
      <div>
        End of Middle Section
      </div>

    </div>
    <div class="right">
      <h2>
        Right
      </h2>
      <ul class="menu">
        <li>
          Side Bar Content Item
        </li>
        <li>
          Side Bar Content Item
        </li>
        <li>
          Side Bar Content Item
        </li>
        <li>
          Side Bar Content Item
        </li>
        <li>
          Side Bar Content Item
        </li>
        <li>
          Side Bar Content Item
        </li>
        <li>
          Side Bar Content Item
        </li>
        <li>
          Side Bar Content Item
        </li>
        <li>
          Side Bar Content Item
        </li>
        <li>
          Side Bar Content Item
        </li>
        <li>
          Side Bar Content Item
        </li>
        <li>
          Side Bar Content Item
        </li>
        <li>
          Side Bar Content Item
        </li>
        <li>
          Side Bar Content Item
        </li>
        <li>
          Side Bar Content Item
        </li>
        <div>
          End of Right Section
        </div>
      </ul>
    </div>
  </div>

</div>
Abdelrahman
  • 525
  • 1
  • 4
  • 13