Scroll Appear documentation

Making elements appear on the page via an animation as the user scrolls down and they enter the viewport is a reasonably common design pattern, but it's often implemented in a way that neglects accessibility and relies on cumbersome JavaScript for its animation.

Scroll Appear is my attempt at implementing this pattern in a way that remains accessible and relies entirely on CSS for its appearance animations.

To accomplish this, Scroll Appear comes in two parts. The first is the JavaScript that handles the functionality of changing elements' states as they enter the viewport. The second is a SCSS mixin that makes it easy to implement these appearance animations in an accessible way.

Installation

Scroll Appear can be installed from npm:

npm install @cipscis/scroll-appear --save

Usage

JavaScript

The JavaScript for Scroll Appear initialises itself, you just need to have it run on the page:

import '@cipscis/scroll-appear';

This JavaScript looks for any element with a js-scroll-appear class on them, and will transition them from hidden, to appearing, to visible as they enter the viewport.

Any elements that are added to the page after Scroll Appear runs will be detected by a MutationObserver and initialised in the same way.

Elements are queued to appear when they first enter the viewport. If an element then leaves the viewport before it appears, it will appear immediately to allow the queue to "catch up" with the viewport.

Elements will also appear immediately if keyboard focus enters them.

SCSS

Scroll Appear contains a SCSS file that exposes a mixin to make it easier to set up the CSS transition used when they appear. The idea behind it is that you should specify the hidden state of the element, and allow it to transition to its default state.

You can import this mixin from the installed Node.js package. The relative path will depend on how your project is organised, but for example:

@import "../../../../node_modules/@cipscis/scroll-appear/scroll-appear";

For example, this CSS sets a hidden element to be faded out and offset to the bottom, so when it transitions to its default state it will fade in and slide up:

.appearing-element { @include scroll-appear(0.5s, ease-in) { opacity: 0; transform: translateY(100px); } }

The two arguments of the scroll-appear mixin are optional, to allow additional control of the duration and easing function of the transition. The default values are 0.3s and ease-in-out.

It is important for accessibility that elements aren't given display: none; or visibility: hidden; within this mixin. They should still be able to be read by screen readers and receive focus from the keyboard even before Scroll Appear has told them to appear.

Accessibility is built into this mixin by having it respect the prefers-reduced-motion media query. So users who prefer reduced motion will not have these elements animate in for them.

No JavaScript

In the event that someone loads your page without JavaScript, you will want to ensure these elements are all visible by default. To allow this level of support, the scroll-appear SCSS mixin is set up so that its contents won't apply if the body element has the CSS class no-js.

This is a common pattern, used by frameworks such as Modernizr, to detect in CSS whether or not a page has JavaScript enabled. You can set this support up by adding the no-js class to your body tag and inserting this inline script to remove it as its very first child:

document.body.classList.remove('no-js');

It's also common to replace it with another class, such as js, but Scroll Appear only looks for a no-js class.

Queues

If an element is configured to have a delay, then the next element should not appear immediately. To accomplish this, elements are added to a queue when they enter the viewport. By default, all elements enter the same queue, but they can also be grouped in two different ways into other queues.

First, if an element has a data-scroll-appear-queue attribute, then it will enter the same queue as all other elements with the same attribute value.

Second, if an element is an ancestor of an element with the class js-scroll-appear__container, then it will enter a queue associated with that container.

Otherwise, an element will join the global queue instead.

Configuration

There are a few ways elements can be configured via data attributes:

Delay

If an element has a number in a data-scroll-appear-delay attribute, the next element in its queue will wait that many milliseconds before appearing.

Queue

If an element has a data-scroll-appear-queue attribute, it will belong to the same queue as all other elements with the same attribute value.

Examples

These example squares have different delay times and belong to different queues. They are colour-coded according to which queue they belong to, and their content is the length of their delay.

They have tabindex="0" so you can Tab through them and see how they appear immediately when they receive keyboard focus. Because they are faded out but have display and visibility modes that mean they are technically visible, you can also click on them to make them appear.

The last item is added to the DOM after Scroll Appear was initialised.