A consumer requested if we might mimic the “rubber band” scrolling habits on many cellular gadgets. I’m certain what I’m speaking about. It’s a habits that already exists and occurs robotically in most browsers. In iOS Safari, for instance, you’re allowed to scroll past the highest or backside fringe of the viewport by a couple of hundred pixels, and letting go snaps the web page again in place.
I had heard of some situations the place somebody may need to forestall the bounce from taking place however nobody had requested me to implement it, particularly in a manner that helps gadgets and not using a contact interface. I used to be truly a bit shocked there isn’t an present CSS property for this. There’s the non-standard -webkit-overflow-scrolling
property however that’s for a unique kind of “momentum” scrolling. Nor would I need to depend on a non-standard property that’s not on observe to develop into a part of the specs.
OK, so what if we need to drive this type of rubber banding in our work? For starters, we’d want some type of component appearing as a container for content material that requires scrolling. From there, we might attain for JavaScript, after all, however that includes including scroll listeners or a mix of pointerDown
, pointerUp
, and pointerMove
occasions, to not point out holding observe of positions, inertial motion, and so on.
A CSS-only resolution can be way more preferrred.
Here’s a container with a couple of youngster components:
<div class="carousel">
<div class="slides">
<div class="slide">1</div>
<div class="slide">2</div>
<div class="slide">3</div>
<div class="slide">4</div>
<div class="slide">5</div>
</div>
</div>
Let’s get some baseline kinds in place, particularly to create a scenario the place we’re assured to overflow a dad or mum container.
/* Mother or father container with fastened dimensions for overflow */
.carousel {
width: 200px;
top: 400px;
overflow-x: hidden;
overflow-y: auto;
}
/* Wrapper for slides, stacked in a column */
.slides {
show: flex;
flex-direction: column;
flex-wrap: wrap;
width: 100%;
top: fit-content;
}
/* Every slide is the total width of the carousel */
.slide {
width: 100%;
aspect-ratio: 1;
}
Let’s begin by including some vertical margins. In case your container has just one lengthy merchandise, add it to the highest and backside of the kid component. If the container has a number of youngsters, you’ll need to add margin
to the highest of the primary youngster component and the underside of the final youngster component.
.carousel > .slides > .slide:first-child {
margin-top: 100px;
}
.carousel > .slides > .slide:last-child {
margin-bottom: 100px;
}
Nice! We are able to now scroll previous the sides, however we’d like one thing to snap it again after the person lifts their finger or pointer. For this, we’ll want the scroll-snap-type
and scroll-snap-align
properties
.carousel {
scroll-snap-type: y obligatory;
}
.carousel > .slides > .slide {
scroll-snap-align: begin;
}
.carousel > .slides > .slide:first-child {
margin-top: 100px;
}
.carousel > .slides > .slide:last-child {
scroll-snap-align: finish;
margin-bottom: 100px;
}
Be aware that the identical applies to a horizontally scrolling component. For that, you’d change issues up in order that margin
is utilized to the component’s left and proper edges as an alternative of its prime and backside edges. You’ll additionally need to change the scroll-snap-type
property’s worth from y obligatory
to x obligatory
whilst you’re at it.
That’s actually it! Right here’s the ultimate demo:
I do know, I do know. This isn’t some Earth-shattering or mind-blowing impact, however it does remedy a really particular scenario. And if you end up in that scenario, now you will have one thing in your again pocket to make use of.
Extra assets