wessberg / scroll-behavior-polyfill

A polyfill for the 'scroll-behavior' CSS-property
MIT License
102 stars 17 forks source link

css scroll-snap fights scroll animation #5

Closed Nemo64 closed 5 years ago

Nemo64 commented 5 years ago

There is now pretty good support for css scroll snap. But when used with this polyfill (in safari) the scroll snap points and this polyfill kind of fight for control.

There are no callbacks or anything to try it but i'd like to set scroll-snap-type to none during the animation.

So I either need callbacks or maybe even an implementation of what i'm trying... or both.

Nemo64 commented 5 years ago

I implemented a Workaround like this:

// fix scroll snap vs scroll-behavior-polyfill fight
const disableScrollSnap = () => document.scrollingElement.style.scrollSnapType = 'none';
const enableScrollSnap = () => document.scrollingElement.style.scrollSnapType = '';
window.addEventListener('wheel', enableScrollSnap, passiveEvents.hasSupport ? {passive: true} : false);
window.addEventListener('touchstart', enableScrollSnap, passiveEvents.hasSupport ? {passive: true} : false);
document.addEventListener('click', disableScrollSnap, true);
disableScrollSnap();

This needs to be in the block executed when the polyfill is loaded.

wessberg commented 5 years ago

Hi there. Sorry for the late reply! Thanks for bringing this to my attention. I'll see if I can add special case handling for this. Do you have a repro I can take a look at where I can easily replicate the behavior you are observing in Safari?

Nemo64 commented 5 years ago

I tried to create a small fiddle but it had the problem that safari does not seem to support scroll-snap in iframes? I'm not entirely sure but I created a small html file that reproduces it:

<!DOCTYPE html>
<html>
<head>
    <title>demo</title>
    <style>
        html, body {
            scroll-snap-type: y proximity;
            scroll-behavior: smooth;
        }

        [id^=a] {
            height: 90vh;
            border: 5px solid black;
            scroll-snap-align: center;
        }

        [id^=a]:nth-child(odd) {
            background-color: green;
        }
    </style>
</head>
<body scroll-behavior="smooth">
    <ul style="position: fixed; left: 0; top: 0; background: white;">
        <li><a href="#a1">anker1</a></li>
        <li><a href="#a2">anker2</a></li>
        <li><a href="#a3">anker3</a></li>
        <li><a href="#a4">anker4</a></li>
    </ul>
    <div id="a1">1</div>
    <div id="a2">2</div>
    <div id="a3">3</div>
    <div id="a4">4</div>
    <script crossorigin src="https://polyfill.app/api/polyfill?features=scroll-behavior"></script>
</body>
</html>
wessberg commented 5 years ago

Thanks for your repro!

I've fixed this issue and have released it as part of v2.09. It isn't yet live on polyfill.app if that's what you're using. Please report back to me if you still experience issues.

simeyla commented 3 years ago

Just as a point of reference - I am using:

And I still see this awful 'fighting' behavior when doing element.scrollTo({ behavior: 'smooth', left: 1000 }) (which would skip several slides) - even with the native scrolling (which is still behind a flag).

scroll-snap-stop: normal is supposed to allow scrolling to 'pass over' snap stops but it just doesn't seem to work.

gluecksmensch commented 3 years ago

I can confirm, scrollTo doesn't work with scroll-snap-type applied to an element.