[ad_1]
A customer asked if we could imitate this “Rubber band” scrolling behavior on many mobile devices. You probably know what I mean. It’s a behavior that’s already present in most browsers and happens automatically. In iOS Safari, for example, you can scroll a few hundred pixels past the top or bottom of the viewport, and when you let go, the page slides back into place.
I have heard of some cases where someone may want to prevent the jump but nobody had asked me to implement it, especially in a way that supports non-touch devices. I was actually a little surprised that there is no existing CSS property for this. There is the non-standard -webkit-overflow-scrolling
Property, but that is for a different kind of Momentum scrollingNor do I want to rely on a non-standard feature that is unlikely to become part of the specifications.
OK, what if we want to enforce this kind of rubberbanding in our work? First of all, we would need some kind of element that acts as a container for content that needs to be scrolled. From there, we could of course resort to JavaScript, but that would require scroll listeners or a combination of pointerDown
, pointerUp
And pointerMove
events, not to mention tracking positions, inertial motion, etc.
A pure CSS solution would be much more ideal.
Here is a container with some child elements:
Let’s set up some basic styles, especially to create a situation where a parent container is guaranteed to overflow.
/* Parent container with fixed dimensions for overflow */
.carousel {
width: 200px;
height: 400px;
overflow-x: hidden;
overflow-y: auto;
}
/* Wrapper for slides, stacked in a column */
.slides {
display: flex;
flex-direction: column;
flex-wrap: wrap;
width: 100%;
height: fit-content;
}
/* Each slide is the full width of the carousel */
.slide {
width: 100%;
aspect-ratio: 1;
}
Let’s start by adding some vertical margins. If your container has only one long element, add it to the top and bottom of the child element. If the container has multiple children, you should add: margin
to the top of the first child element and to the bottom of the last child element.
.carousel > .slides > .slide:first-child {
margin-top: 100px;
}
.carousel > .slides > .slide:last-child {
margin-bottom: 100px;
}
Great! We can now scroll beyond the edges, but we need something to push it back after the user lifts their finger or pointer. For this we need the scroll-snap-type
And scroll-snap-align
Characteristics
.carousel {
scroll-snap-type: y mandatory;
}
.carousel > .slides > .slide {
scroll-snap-align: start;
}
.carousel > .slides > .slide:first-child {
margin-top: 100px;
}
.carousel > .slides > .slide:last-child {
scroll-snap-align: end;
margin-bottom: 100px;
}
Note that the same applies to a horizontal Scroll Element. To do this, you would change things so that margin
is applied to the left and right edges of the element instead of the top and bottom edges. You should also scroll-snap-type
Value of the property of y mandatory
To x mandatory
while you’re at it.
That’s it! Here is the finished demo:
I know, I know. It’s not an earth-shattering or mind-blowing effect, but it does solve a very specific situation. And when you find yourself in that situation, you now have something in reserve that you can use.
Additional resources
[ad_2]
Source link