Slide stacking effect using position sticky
Tags: css, tutorial, webdev
Published: 2019-09-11 17:29:35

---
title: Slide stacking effect using position sticky
published: true
description: Slide stacking effect using position sticky on scroll.
tags: CSS, tutorial, webdev 
canonical_url: https://vinceumo.github.io/devNotes/CSS/slide-stacking-effect-using-position-sticky/
cover_image: https://thepracticaldev.s3.amazonaws.com/i/s6ajomsdfmvtczlx6aq2.jpg
---

![Demo gif](https://vinceumo.github.io/devNotes/scroll-gif.gif)

Recently I was looking to create a slide (card) stacking effect on scroll. The closest resource I could find about this effect was [Card Stack: Scroll Effect by Sanjeev Yadav](https://medium.com/@sanjeevy133/card-stack-scroll-effect-486cc3b55312). I wanted to look if I could recreate a similar effect only with CSS.

## Basic effect with position sticky

Position sticky enables to position an element like position fixed relative to its parent until it reaches the boundary of the parent.

> Sticky positioning can be thought of as a hybrid of relative and fixed positioning. A stickily positioned element is treated as relatively positioned until it crosses a specified threshold, at which point it is treated as fixed until it reaches the boundary of its parent. 
>
> [MDN - Sticky positioning](https://developer.mozilla.org/en-US/docs/Web/CSS/position#Sticky_positioning)

We can use position sticky to stick each slide, at the top at the parent and have a fixe height.

CSS:

```scss
.stacking-slide {
    height: 100vh;
    width: 100%;
    position: sticky;
    top: 0;
  
//   Not needed if 100vh
//   &:nth-last-child(1) {
//      height: 100vh;
//   }
}
```

HTML:

```html
<section class="stacking-slide">
    <h2>Section 1</h2>
</section>
<section class="stacking-slide">
    <h2>Section 2</h2>
</section>
<section class="stacking-slide">
    <h2>Section 3</h2>
</section>
<section class="stacking-slide">
    <h2>Section 4</h2>
</section>
<section class="stacking-slide">
    <h2>Section 5</h2>
</section>
```


{% codepen https://codepen.io/vinceumo/pen/KKPoVGL/ default-tab=result %}


### Support

Position sticky has great support ([Can I Use](http://caniuse.com/#feat=css-sticky)), but if you need to support older browsers you can use a [polyfill](https://github.com/wilddeer/stickyfill/).

## Vertical Scroll Snap

CSS scroll snap permits us to make each slide position nicely at the top of the viewport after scroll.

> CSS Scroll Snap is a module of CSS that introduces scroll snap positions, which enforce the scroll positions that a scroll container’s scrollport may end at after a scrolling operation has completed.
>
> [MDN - CSS Scroll Snap](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Scroll_Snap)

To use scroll snap we are going to wrap our sections into `.vertical-scroll-snap`. This element is going to have a fixe height of 100vh and `overflow-y: scroll` so the user can scroll between sections.

Next step we are going to look into scroll snap. First we are going the set `scroll-snap-type` ([MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-snap-type)). This property defines how strictly snap points are enforced on scroll. We are going to set it to `y mandatory`. `y` is indicating that the snap positions is in its vertical axis only. `mandatory` that the scroll container will rest on a snap point of the section if it isn't currently scrolled.

Then we need to tell our sections which part need to be aligned to the container. We are going to use `scroll-snap-align` ([CSS Tricks](https://css-tricks.com/almanac/properties/s/scroll-snap-align/)) with the value `start`.

HTML:

```html
<div class="vertical-scroll-snap">
  <section class="stacking-slide">
    <h2>Section 1</h2>
  </section>
  <!-- ... -->
</div>
```

SCSS:

```scss
.vertical-scroll-snap {
    overflow-y: scroll;
    scroll-snap-type: y mandatory;
    max-height: 100vh;
}

.stacking-slide {
    scroll-snap-align: start;
    // ...
}
```

{% codepen https://codepen.io/vinceumo/pen/aboYLBW/ default-tab=result %}


### Support

CSS Scroll snap has good support ([Can I Use](http://caniuse.com/#feat=css-snappoints)), if you need to support older browsers you can use a [polyfill](https://www.npmjs.com/package/css-scroll-snap-polyfill).

## Add some nice transition using Intersection Observer API.

The Intersection Observer API, lets us to detect when an element enters the viewport. We can trigger a callback function when this element enters or leave the viewport.

> The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document's viewport.
>
> [MDN - Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)

In the following example, we are adding the class `.is-intersecting` when a `.stacking-slide` enter 10% of the viewport. And we remove this class when the slide leaves it. We can now add some nice transitions using CSS.

JS:

```js
const sectionEls = document.querySelectorAll(".stacking-slide");

const options = {
  rootMargin: "-10% 0% -10% 0%"
};

const observer = new IntersectionObserver(entries => {
  entries.forEach(function(entry) {
    if (entry.isIntersecting) {
      entry.target.classList.add("is-intersecting");
    } else {
      entry.target.classList.remove("is-intersecting");
    }
  });
}, options);

sectionEls.forEach(el => observer.observe(el));
```

{% codepen https://codepen.io/vinceumo/pen/WNeJRZo/ default-tab=result %}


### Support

The Intersection Observer API has good support ([Can I Use](http://caniuse.com/#feat=intersectionobserver)), if you need to support older browsers you can use a [polyfill](https://github.com/w3c/IntersectionObserver/tree/master/polyfill).

---

Thanks for reading hope you enjoyed this small article.

- [Follow me on twitter](https://twitter.com/vince_umo)
- [Follow me on Github](https://github.com/vinceumo)
- [Follow me on dev.to](https://dev.to/vinceumo)