简体   繁体   中英

How to make a sticky scrolling effect that stays at the top a little and immediately pops off

Sorry for such a dumb question for you, I've got a list of elements with overflow-y:auto, like this: 在此输入图像描述

I'd like to make them stick for just a little bit when I'm scrolling and pop off when the next one is pushing it from the bottom.

It's to avoid this which IMO doesn't look very good. 在此输入图像描述

I know I have to use position:sticky but I don't know how to achieve this without the elements staying there definitely as I scroll down

to make this you would use css-snap:

for the list class: add the following css:

.parent { 
    overflow: scroll;
    height: 200px;
    scroll-snap-type: y mandatory;
      scroll-snap-points-y: repeat(50px);
}
.child { 
    height: 50px;
    margin: 10px;
    scroll-snap-align: start;
}

replace:

.parent with your list class,

height: 200px with your list height, notice that you should give it specific height,

scroll-snap-points-y: repeat(50px) replace 50px with height of children, in my case i used 50px because child class has height of 50px.

.child with your element class

height: 50px height of children element.

 .parent { overflow: scroll; height: 200px; scroll-snap-type: y mandatory; scroll-snap-points-y: repeat(50px); } .child { height: 50px; margin: 10px; scroll-snap-align: start; } .child:nth-child(even) { background-color: #ccc; } .child:nth-child(odd) { background-color: #ddd; } 
 <div class="parent"> <div class="child"><h1>testing</h1></div> <div class="child"><h1>testing</h1></div> <div class="child"><h1>testing</h1></div> <div class="child"><h1>testing</h1></div> <div class="child"><h1>testing</h1></div> <div class="child"><h1>testing</h1></div> <div class="child"><h1>testing</h1></div> <div class="child"><h1>testing</h1></div> <div class="child"><h1>testing</h1></div> <div class="child"><h1>testing</h1></div> <div class="child"><h1>testing</h1></div> <div class="child"><h1>testing</h1></div> <div class="child"><h1>testing</h1></div> <div class="child"><h1>testing</h1></div> <div class="child"><h1>testing</h1></div> <div class="child"><h1>testing</h1></div> </div> 

Please excuse the lengthy code, as the HTML and parts of the CSS were just meant to make things stand out.

The actual core of it is the JavaScript code, along with the parts of CSS I didn't comment on.

Obviously the code's readability can be improved; However I've intentionally left the original functions, rather than writing custom ones (eg makeTopElement(element) , or getTopPosition(element) ), as the code snippet has already become pretty long vertically.

 const items = document.getElementsByClassName('item'); const itemHeight = items[0].getBoundingClientRect().height; let currentTopIndex = 0; let prevY = 0; document.onscroll = function() { let currY = window.pageYOffset; // Scrolling down if (currY > prevY && currentTopIndex < items.length - 1 && items[currentTopIndex + 1].getBoundingClientRect().top < itemHeight) { items[currentTopIndex].classList.remove('top'); items[currentTopIndex].style.top = 'auto'; items[currentTopIndex].style.bottom = 0; currentTopIndex ++; items[currentTopIndex].classList.add('top'); } // Scrolling up else if (currY < prevY && currentTopIndex > 0 && items[currentTopIndex - 1].getBoundingClientRect().top > 0) { items[currentTopIndex].classList.remove('top'); currentTopIndex --; items[currentTopIndex].classList.add('top'); items[currentTopIndex].style.top = 0; items[currentTopIndex].style.bottom = 'auto'; } prevY = currY; }; 
 .wrapper { height: 500px; } .itemWrapper { height: 100px; position: relative; } .item { position: absolute; /* These properties are here just to make things pretty */ background-color: MintCream; padding: 10px; text-align: center; border: 1px solid #00e673; width: 100%; } .top { position: sticky; top: 0; /* These properties are here just to make things pretty */ background-color: red; border-color: #990000; } 
 <div class="wrapper"> <div class="itemWrapper"> <div class="item top"> first </div> </div> <div class="itemWrapper"> <div class="item"> second </div> </div> <div class="itemWrapper"> <div class="item"> third </div> </div> </div> 

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