Skip to content

Parallax library that offers CSS variables useful for style-based effects.

License

Notifications You must be signed in to change notification settings

Ken-Vermette/kv-parallax

Repository files navigation

KV Parallax

A standalone library that provides CSS variables for parallax effects without additional javascript.


Compatibility Goals

KV Parallax is intended to work on modern "full-fat" browsers. Minimal browsers such as Opera Mobile which do not support many CSS operations are fundamentally incompatible with this library and its usage.


Getting Started

Installation

1. Using the self-initializing version

If you don't need to modify the options then this is the reccomended version to use.

  1. Download the parallax package and copy kv-quick-parallax.min.js to your website.
  2. Add the script to your website.
<script src="path/to/kv-quick-parallax.min.js"></script>
  1. Ready! 🎉

2. Using the non-initializing version

If you do need to modify the options before parameters are written to the DOM then this is the reccomended version to use. Use this version if...

  • You have CSS variables starting with --parallax
  • You need to change the CSS class.
  • You want more than 3 decimals of accuracy.
  1. Download the parallax package and copy kv-parallax.min.js to your website.
  2. Add the script to your website.
<script src="path/to/kv-quick-parallax.min.js"></script>
  1. Call the init function in your onload handler, you may modify the values as appropriate or leave them out for the default values.
kvParallax.init({
    className: 'css-parallax',
    cssPrefix: 'parallax-',
    decimalAccuracy: 3,
});
  1. Ready! 🎉

3. Optionally add this to your CSS

On first load it's possible there may be a slight flicker as elements aren't positioned properly until the library kicks in. Adding this CSS to your main stylesheet makes sure these variables are at least present, and if there is any reflow it's far improved. If your website uses loading overlays you probably won't need to do this.

:root {
	--parallax-scroll-x: 0;
	--parallax-scroll-y: 0;
	--parallax-coverage-x: 1;
	--parallax-coverage-y: 1;
	--parallax-cubic-x: 0;
	--parallax-cubic-y: 0;
	--parallax-visible: 1;
	--parallax-half-visible: 1;
	--parallax-quarter-visible: 1;
}

4. Optionally pair with a Firefox/Async browser fix

... And why Firefox makes me sad...

Firefox (and kin) use asynchronous scrolling. Essentially breaking drawing, scrolling, and event handling into separate event loops. This extraordinarily terrible idea means that parallaxing can't be done smoothly. In theory it improves performance, in practise it just breaks things with no benefit. For some reason Mozilla is holding strong on this misguided implementation.

The good news is there are libraries that can alleviate this, somewhat. It's 2021 and I'm including a script that uses browser sniffing to fix broken implementations.

Keith Clark has an implementation from ...2011... which helps Firefox with this very basic rendering challenge. Of note this does break smooth scrolling, and if a user scrubs the scrollbar things still aren't pretty, but it definitly makes parallax effects go from "unusable" to "good enough". You can see his work here:

https://keithclark.co.uk/articles/faster-scrolling-parallax-websites-in-firefox/

The scripts are available as clark-firefox-helper.js and clark-firefox-helper.min.js. Kindly note that they are MIT licensed. You can include them directly or use a sniffing mechanism if you have a javascript loader. I reccomend the minified version. I'm not maintaining these, it's a script from 2011, use at your own peril, I'm not fixing the warning I know it generates.

<script src="path/to/clark-firefox-helper.min.js"></script>

Usage

At its core KV Parallax provides several dynamic CSS variables to elements with the css-parallax class. For typical usage you do not need to write additional javascript.

All values generated by parallax are normalised to between -1 and 1, and are unitless. Use these variables in CSS with the "calc" function and multiply them with some desired unit.

CSS Variables Provided Out-of-Box

--parallax-scroll-[x|y]

Returns the "progress" of the element on screen. If you use something like calc(100%var(--parallax-scroll-y)) you'll get the percentage offset for simple background parallaxing.

  • returns -1 to 1
  • Minimum is -1; when the 'start' of an element is first entering viewport from either the bottom or right..
  • At 0 the center of the element is on the center of the screen.
  • Maximum is 1; when the 'end' of an element is leaving the viewport.

--parallax-cubic-[x|y]

Similar to the parallax scroll functions, but instead of being strictly linear in progession a cubic function is applied. Great when you want something to move in and out with a bit more "oomph".

--parallax-coverage-[x|y]

If multiplied by 100, this becomes the percentage of the elements' visibility on a given access.

  • returns 0 to 1
  • Minimum is 0: None of the element is visible on the axis.
  • Maximum is 1: Either the element is completly visible, or covers the axis.

--parallax-visible

Use this if you want to target fixed children extending beyond the edge of a tracked element. Using this in tandem with transitions is optimal.

  • returns 0 OR 1
  • Value of 0: The element is not currently on screen.
  • Value of 1: Any amount of the element is on screen.

--parallax-half-visible, --parallax-quarter-visible

Same as --parallax-visible, but requires at least quarter or half of a tracked element to be visible before returning 1. These are designed to be used in tandem with a CSS transition.

  • returns 0 OR 1
  • Value of 0: Not enough of the element is on screen.
  • Value of 1: Enough of the element is on screen.

Adding custom CSS variables

You may add custom CSS variables via kvParallax.addCssVariable. It takes two parameters: name and callback. The name being the CSS variable to be added, and callback being your logic.

The callback takes two parameters: event and domElement. The event is an object with the following properties:

  • xScrollProgress: between -1 and 1. Used by --parallax-scroll-x.
  • yScrollProgress: between -1 and 1. Used by --parallax-scroll-y.
  • xCoverage: between 0 and 1. Used by --parallax-coverage-x.
  • yCoverage: between 0 and 1. Used by --parallax-coverage-x.

The domNode is the element being calculated, should you need to perform calculations on it.

Here is an example of a custom function, and the CSS to use it:

This will generate a value that will make a parallax "wave" 3 times.
kvParallax.addCssVariable('wavy-effect', (e, el) => {
    return Math.sin(Math.PIe.yScrollProgress3);
});
.my-wavy-thing {
  left: calc(100px * var(--parallax-my-wavy-effect));
}

Accessing Expando Parallax values in Javascript

If you're looking to use the parallax values in script, tracked elements will have access to the expando property "kvParallaxData". It has the same four values offered in the addCssVariable event.

  • xScrollProgress: between -1 and 1. Used by --parallax-scroll-x.
  • yScrollProgress: between -1 and 1. Used by --parallax-scroll-y.
  • xCoverage: between 0 and 1. Used by --parallax-coverage-x.
  • yCoverage: between 0 and 1. Used by --parallax-coverage-x.

Using these values in conjunction with requestAnimationFrame calls you can apply specialty logic.

In general the only real reason to use this is if you're drawing complex scenes (possibly using 3D) for your parallax effects, or using video and are using scroll positions to determine the video time position. This library isn't built for those effects, but using the expando properties you can keep your own effects in sync with kvParallax.

Cascading Variables and Performance

You do not need to add the css-parallax to absolutley everything. In general if you have several paralaxxing elements in a block of your website, add the css-parallax class to just the parent block. All children will inherit the CSS variables from the parent.

This will make your parallaxing effects synchronized across several child elements, and you'll get better performance.

Note: If the element is off-screen KV Parallax will NOT perform updates to tracked elements. KV Parallax does ensure values are accurate. In general there should be no issues caused by this, but be aware if writing custom logic.

Examples

/* 
 * Control a simple parallaxing background.
 */
.my-parallaxing-thing {
  background-position: center calc(100% * var(--parallax-scroll-y));
}
/* 
 * Control multiple backgrounds. The second background will move more slowly
 * than the first. I reccomend using taller/shorter backgrounds instead of
 * this technique.
 */
.my-parallaxing-thing {
  background-position: 
    center calc(100% * var(--parallax-scroll-y)),
    center calc(100% * (var(--parallax-scroll-y) / 2));
}
/* 
 * If your site scrolls horizontally or you have elements moving horizontally,
 * you can use the x-axis as well.
 */
.my-parallaxing-thing {
  background-position: calc(100% * var(--parallax-scroll-x)) calc(100% * var(--parallax-scroll-y));
}
/* 
 * Get the percentage of screen coverage in CSS.
 * This will make an element shrink in height as it moves out of view.
 */
.my-parallaxing-thing {
  height: calc(100% * var(--parallax-coverage-y));
}
/* 
 * Slide a 200px element into view once quarter of the parent is exposed.
 * It will slide back out once you continue scrolling.
 */
.my-thing-sliding-in {
  position: absolute;
  right: calc(100% - (200px * var(--parallax-scroll-y)));
  transition: right 0.5s;
}

Tips

  • Use CSS min() and max() for clamping. By clamping the --parallax-scroll values via min(0, var(--parallax-scroll)) you can safely ensure some effects only take place on "entry" or "exit".
  • It is strongly reccomended you use CSS math functions as much as possible using this library, in lieu of javascript. The vast majority of parallax effects seen on the web today are possible using CSS variables provided.

About

Parallax library that offers CSS variables useful for style-based effects.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published