A standalone library that provides CSS variables for parallax effects without additional javascript.
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.
If you don't need to modify the options then this is the reccomended version to use.
- Download the parallax package and copy kv-quick-parallax.min.js to your website.
- Add the script to your website.
<script src="path/to/kv-quick-parallax.min.js"></script>
- Ready! 🎉
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.
- Download the parallax package and copy kv-parallax.min.js to your website.
- Add the script to your website.
<script src="path/to/kv-quick-parallax.min.js"></script>
- 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,
});
- Ready! 🎉
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;
}
... 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>
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.
--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.
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));
}
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.
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.
/*
* 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;
}
- 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.