5

I am trying to have a page with vertical scrolling snapped to every paragraph (every photo description). I also want body to be my scrolling container, not some div inside body.

I have:

body.scroll-snap {
  scroll-snap-type: y proximity;
}

.scroll-snap .episode p {
  scroll-snap-align: start;
  scroll-margin: 8px;
}

This works perfectly in Chrome and Safari, but doesn't work in Firefox. Firefox inspector shows these CSS properties applied to tag, but the scroll doesn't snap.

How to make it work in FF without creating additional scrolling containers?

Sergey Kirienko
  • 281
  • 3
  • 12

2 Answers2

5

Apparently the better way is to set html element as your snapping container instead of body. In this case scroll snaps in FF and also in Chrome-like browsers. But it stops working in current Safari. You can fix it by setting scroll-snap-type to both.

Also please note that current Safari doesn't support scroll-margin, but instead supports deprecated scroll-snap-margin (hopefully this will be fixed in future versions).

So my current solution is:

html.scroll-snap {
  scroll-snap-type: y proximity;
}

html.scroll-snap body {
  scroll-snap-type: y proximity;
}

.scroll-snap .episode p {
  scroll-snap-align: start;
  scroll-margin: 8px;
  scroll-snap-margin: 8px; /* works in Safari */
}
Sergey Kirienko
  • 281
  • 3
  • 12
  • An upcoming potential issue with Safari is on iOS 15 where the URL bar appears and disappears. Currently this can interfere even with `scroll-snap-align: start` and end up with items not snapping correctly to the top of the screen. I believe what happened is they forgot to account for the URL bar when calculating the final scroll position. It will work fine most of the time, but can fail if you scroll up and down several times (even with `mandatory`). I'm looking into filing a bug on this behavior. – Simon_Weaver Aug 13 '21 at 02:50
  • Awesome! I pulled my hair out over this because adding an additional container messes with a fixed navbar on top but applying scroll-snap-type directly to body did not work. Your answer makes my code so much simpler and my design better. Thanks a lot! – Fred Jan 06 '22 at 23:11
1

OK, I've found the solution. The following code makes scroll snapping work in Firefox with body as a container.

html {
  height: 100%;
  overflow: hidden;
}

body {
  height: 100%;
  overflow: auto;
}

body.scroll-snap {
  scroll-snap-type: y proximity;
}

.scroll-snap .episode p {
  scroll-snap-align: start;
  scroll-margin: 8px;
}

Then when you have body like <body class="scroll-snap">, scroll snapping will be switched on, and scroll will try to stick on start of every <p> of every container with class name episode.

Sergey Kirienko
  • 281
  • 3
  • 12