Lemme do this one quick-hits style:
- Mary Lou published a quintessentially-Codrops-y demo called Alternate Column Scroll.
- The scrolling effect is powered by Locomotive Scroll, which we’ve coincidentally covered before.
- Bramus has been exploring native CSS scrolling effects using the future CSS Scroll-Timeline feature for a while now. He’s got a four-parter that digs deep into it, starting here.
- It’s early days for it, but
@scroll-timeline
is flagged in Chrome-land. Bramus has also shown us how incredibly useful this feature will be right here on CSS-Tricks, especially when combined with WAAPI. - So, Bramus set out to re-build the scrolling aspects of the demo (the middle column scrolls naturally and the outer two columns scroll in reverse). Turns out you can polyfill it and sprinkle in some WAAPI to replicate it nicely. Cool.
prefers-reduced-motion
CSS Scroll-Timeline with The only thing I’d add is something to honor prefers-reduced-motion
, as I could see this sort of scrolling motion affecting someone with motion sickness. To do that, you could combine tests in the same line the support test is being done in JavaScript:
if (
!CSS.supports("animation-timeline: foo") &&
!window.matchMedia('(prefers-reduced-motion: reduce)').matches
) {
// Do fancy stuff
}
I’m not 100% if it’s best to test for no-preference
or the opposite of reduce
. Either way, the trick in CSS is to wrap anything you’re going to do with @scroll-timeline
and animation-timeline
in an @supports
test (in case you want to do something different otherwise) and then wrap that in a preference test:
@media (prefers-reduced-motion: no-preference) {
@supports (animation-timeline: works) {
/* Do fancy stuff */
}
}
Here’s a demo of that, with all the real credit to Bramus here for getting it going.
Ooo and ya know what? The CSS gets nicer should @when
land as a feature:
@when supports(animation-timeline: works) and media(prefers-reduced-motion: no-preference) {
} @else {
}
It’s worth pointing out that this whole effect can be created without using JS (CSS only).
It can be done using transforms + perspective to make farther elements scroll slower than the rest of the page, then use scale to make the farther items appear to be the same size as the regular elements.
You can also make an element closer to the camera than the rest of the page then scale it back down to make it appear to travel in the opposite direction as the rest of the page.
This example here shows using it for a customised scrollbar, but you could also use it for these scrolling columns by moving them back and scaling them up, or moving them closer and scaling them down, depending on which direction you want them to move on scroll.
Note: That example uses a lot of 3d matrix math which will look familiar to anyone who has done graphics programming and esoteric to everyone, but you can achieve the same result using regular transforms.
Firefox 97 just landed with (according to the developer documentation) support for this. Doesn’t seem to actually work with this demo though. Now I’m wondering whether it’s a problem with the demo or with Firefox’s implementation.