skip to Main Content
.header,
.footer {
  text-align: center;
  height: 300px;
  background: white;
}

.container {
  display: flex;
  width: 600px;
  margin: 0 auto;
  background: #fafafa;
}

.main {
  flex: 0 0 66.6666%;
  height: 1500px;
}

.sidebar {
  flex: 0 0 33.3333%;
  background: gray;
}

.sidebar__widget {
  position: sticky;
  top: 0;
  background: yellow;
}

.margins {
  padding-top: 30px;
  padding-bottom: 30px;
}
<header class="header">header</header>

<div class="container">
  <div class="main">Main</div>
  
  <aside class="sidebar">
    <div class="sidebar__widget">
      <div class="margins">
        text2
      </div>
      <div class="margins">
        text3
      </div>
      <div class="margins">
        text4
      </div>
      <div class="margins">
        text5
      </div>
    </div>
  </aside>
</div>

<footer class="footer">footer</footer>

is not scrolling to div with text5, only if i scrolled all content after.

also i recorded a video for showing a problem:
https://gyazo.com/d5337df7b814c0621ac59c1e85433965

also i tried with display: table, it doesn’t work correctly too

2

Answers


  1. The question might not be perfectly clear, but since you showed a video where you had the .sidebar__widget (yellow container) taller than the viewport, I supposed you meant that such element had to be sticky only after the scrolling showed it entirely.

    To achieve such behaviour you need to change its top css property so that if the viewport is taller, it just remains set as 0, and otherwise it’s set with an offset that will stick it only after it’s fully shown while still scrolling part of its parent container that includes also a longest content on its left side.

    EDIT:
    Using css only was a more desirable option, and I suspect that’s the origin of the downvote on my answer, but (so far according to what I can see now) it would require your sidebar to lay on the bottom of its container and it might have questionable results when the viewport is higher than its height. In that case you wouldn’t see the yellow box starting from the upper edge of its container but you would see it laying on its bottom. Is that what you asked for?

    //sets the .sidebar__widget top css property according to window.innerHeight
    function adjustStickySidebar() {
        var sidebarWidget = document.querySelector('.sidebar__widget');
        var sidebarHeight = sidebarWidget.offsetHeight;
        var windowHeight = window.innerHeight;
    
        if (sidebarHeight < windowHeight) {
            sidebarWidget.style.top = '0px';
        } else {
            sidebarWidget.style.top = `${windowHeight - sidebarHeight}px`;
        }
    }
    
    //Adjust the sticky sidebar on window load and resize
    window.addEventListener('load', adjustStickySidebar);
    window.addEventListener('resize', adjustStickySidebar);
    .header,
    .footer {
      text-align: center;
      height: 300px;
      background: white;
    }
    
    .container {
      display: flex;
      width: 600px;
      margin: 0 auto;
      background: #fafafa;
    }
    
    .main {
      flex: 0 0 66.6666%;
      height: 1500px;
    }
    
    .sidebar {
      flex: 0 0 33.3333%;
      background: gray;
    }
    
    .sidebar__widget {
      position: sticky;
      /*top decides where the elements sticks relative to the container*/
      /*zero works only if the viewport is taller than element's height*/
      top: 0;
      background: yellow;
    }
    
    .margins {
      padding-top: 30px;
      padding-bottom: 30px;
    }
    <header class="header">header</header>
    
    <div class="container">
      <div class="main">Main</div>
      
      <aside class="sidebar">
        <div class="sidebar__widget">
          <div class="margins">
            text2
          </div>
          <div class="margins">
            text3
          </div>
          <div class="margins">
            text4
          </div>
          <div class="margins">
            text5
          </div>
        </div>
      </aside>
    </div>
    
    <footer class="footer">footer</footer>
    Login or Signup to reply.
  2. You need a bottom sticky not a top one. And before that you have to place the element at the bottom as well

    .header,
    .footer {
      text-align: center;
      height: 300px;
      background: white;
    }
    
    .container {
      display: flex;
      width: 600px;
      margin: 0 auto;
      background: #fafafa;
    }
    
    .main {
      flex: 0 0 66.6666%;
      height: 1500px;
    }
    
    .sidebar {
      flex: 0 0 33.3333%;
      background: gray;
      /* add this to place the element at the bottom */
      display: flex;
      flex-direction: column;
    }
    
    .sidebar__widget {
      position: sticky;
      bottom: 0;
      margin-top: auto; /* place at bottom */
      background: yellow;
    }
    
    .margins {
      padding-top: 30px;
      padding-bottom: 30px;
    }
    <header class="header">header</header>
    
    <div class="container">
      <div class="main">Main</div>
      
      <aside class="sidebar">
        <div class="sidebar__widget">
          <div class="margins">
            text2
          </div>
          <div class="margins">
            text3
          </div>
          <div class="margins">
            text4
          </div>
          <div class="margins">
            text5
          </div>
        </div>
      </aside>
    </div>
    
    <footer class="footer">footer</footer>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search