0

I have some issues considering scroll-snap-align in css, probably due to a familiar bug in chrome.
I have found two ways to make the scroll-snap-align work, but both ways won't properly.
  1. Option 1 - use the scroll-snap-type in the html tag:
html {
   scroll-snap-type: y mandatory;
}

article {
   /* empty */
}

section {
   scroll-snap-align: start;
}
  1. Option 2 - use the scroll-snap-type in the container (article) tag:
html {
   /* empty */
}

article {
   scroll-snap-type: y mandatory;
}

section {
   scroll-snap-align: start;
}

The problem is that option 1 cause the double-scroll bug in chrome, and I haven't found a way to fix it (changing the background color didn't work for me), and option 2 just won't do anything at all, same as if I didn't write this lines of code.

I have also tried playing with overflow-y, overscroll-behavior-y or changing the height of the container, but none of them fixed the issue.

I'd be very thankful for anyone who will try to help me :)

P.S I'm using create-react-app if it matters somehow.

Yoni
  • 23
  • 7
  • What is the chrome double-scroll bug? – Trevin Avery Mar 25 '21 at 11:25
  • What is your HTML structure? Is `section` a direct child of `article`? – Trevin Avery Mar 25 '21 at 11:28
  • The double-scroll bug is described well in here: https://stackoverflow.com/questions/64581125/website-double-scrolling-on-chrome-using-scroll-snap-type And yes to the second question. The tree is basically: html -> body -> { ...some divs... } -> article -> section – Yoni Mar 25 '21 at 12:17
  • I'm using Chrome 89.0.4389.90. Looking at the example in that post, it appears to be working just fine now. Can you provide a full snippet of your code that shows the bug? – Trevin Avery Mar 25 '21 at 16:32
  • My version is the same, and the code is long but you can see the result here: https://msimyan.com/ (in the inspector of course). notice that the problem appears only when you're using the mouse's scroll, not the scroll bar. – Yoni Mar 25 '21 at 19:33

1 Answers1

2

The key is you need to make sure the element you have set to scroll snap is actually the one being scrolled.

In your case, although you placed the scroll-snap-type property on your article element, the article is free to stack its content and fill its parent. Thus, when you scroll, the html element is being scrolled, not the article element.

To fix this, simply add

article {
    scroll-snap-type: y mandatory;
    height: 100vh; /* match the height of the screen */
    overflow-y: scroll; /* force it to scroll */
}

This will work as you expect. However, because your footer element is outside the article, when you reach the bottom, it will scroll the html element to show it. Then, if you scroll up on the article and not the footer, the footer will remain and your article will only be partially visible.

Therefore, I would suggest you actually add the above styling to your div#root element, and add scroll-snap-align: start; to your footer. This should make the scrolling work nicely.

Trevin Avery
  • 2,751
  • 2
  • 20
  • 31
  • OK I understand much better how scrollbars work (still don't understand why I must put `height: 100vh` but whatever). It also worked when I put this code under `body` and not `article` which includes the footer, but the problem is now different - the navbar is above my scroll-bar :( I tried to add the next code to my css: `body::-webkit-scrollbar { z-index: 1; }` and changed the z-index to any number, but it won't help. Any suggestions? – Yoni Mar 27 '21 at 10:12
  • Another problem I found out - the `scrollIntoView` function won't work, I guess because we don't scroll the `html` anymore but the `body` instead. Should I just give up on the scroll-snap and finish with it? – Yoni Mar 27 '21 at 10:34
  • 1
    No! [Never give up. Never surrender!](https://www.youtube.com/watch?v=9fdcIwHKd_s&ab_channel=retroelectrical) Every element can be scrolled. By default, the size of an element will be large enough to show all of its contents; therefore, it will have no need to scroll. This is true for all but the `html` element, which is bound by the viewport size. This is why the `html` element is the default element that scrolls. We set the height of the element you want to scroll so that it doesn't expand large enough to show all of its content without scrolling. – Trevin Avery Mar 27 '21 at 20:31
  • Additionally, you have to tell it not to show the overflow, or again, the scrolling will default to the next parent set to scroll. We used `100vh` because that will always be the height of the viewport (the entire window). The navbar is above your scrollbar because it is above the element that is scrolling. You can move the navbar inside the scrolling element before positioning it so it will be included in the scroll. The `scrollIntoView` function must be called on the scrolling element. Something like `document.querySelector('body').scrollIntoView()`. – Trevin Avery Mar 27 '21 at 20:36
  • Thanks a lot man, you really helped me :) – Yoni Mar 28 '21 at 08:16