In this tutorial we’re going to use the Rellax JS parallax scrolling library to create the effect of rising bubbles as parallax sprites. It’s purely decorative – just for a bit of fun. Although we’re using simple CSS bubbles, you can easily add your own shapes, and control which posts will have the effect applied.
importantMake sure you’re using a custom child theme so you can edit functions.php
Thanks to Richard for the idea for the tutorial 👍
Parallax Sprites
Scaffold the Code
Let’s jump straight in. Go in to your child theme, create a new file called wpt-parallax-sprites.php and paste the following into it:
<?php /** * WP Tutorials : Parallax Sprites (WPTPLX) * * https://wp-tutorials.tech/add-functionality/parallax-scrolling-sprites-with-rellax-js/ */ defined('WPINC') || die(); const WPTPLX_RELLAX_VERSION = '1.12.1'; const WPTPLX_META_ENABLE_PARALLAX = '_parallax_sprites'; const WPTPLX_DEFAULT_SPRITE_COUNT = 150; const WPTPLX_CONTAINER_CLASS = 'wptplx-sprite'; const WPTPLX_ROOT_CONTAINER_SELECTOR = 'body'; // #content /** * Enqueue the front-end assets for WP Tutorials Parallax Sprites. */ function wptplx_wp_enqueue_scripts() { if (!is_singular()) { // The user is not trying to view a single content item. } elseif (!filter_var(get_post_meta(get_the_ID(), WPTPLX_META_ENABLE_PARALLAX, true), FILTER_VALIDATE_BOOLEAN)) { // The _parallax_sprites post meta is not TRUE for this post/page. } else { $theme_version = wp_get_theme()->get('Version'); $base_uri = get_stylesheet_directory_uri(); // You can download Rellax JS from here: // https://github.com/dixonandmoe/rellax wp_enqueue_script( 'rellax', $base_uri . '/wpt-parallax-sprites/rellax.min.js', null, WPTPLX_RELLAX_VERSION ); // This is our main JavaScript code. wp_enqueue_script( 'wpt-parallax-sprites', $base_uri . '/wpt-parallax-sprites/parallax-sprites.js', array('rellax'), $theme_version ); // We pass some data to our front-end JavaScript code in the wptplxData // object. wp_localize_script( 'wpt-parallax-sprites', 'wptplxData', // << You can access this object in the browser. array( 'rootContainerSelector' => WPTPLX_ROOT_CONTAINER_SELECTOR, 'spriteClasses' => wptplx_get_sprite_classes(), 'containerClass' => WPTPLX_CONTAINER_CLASS, 'spriteCount' => WPTPLX_DEFAULT_SPRITE_COUNT, ) ); // The styles for our sprites. wp_enqueue_style( 'wpt-parallax-sprites', $base_uri . '/wpt-parallax-sprites/parallax-sprites.css', null, $theme_version ); } } add_action('wp_enqueue_scripts', 'wptplx_wp_enqueue_scripts'); /** * This should return an array of CSS class names to apply to our sprites. * Each sprite will have the "wptplx-sprite" class and one of the following * random classes. */ function wptplx_get_sprite_classes() { global $wptplx_sprite_classes; if (is_null($wptplx_sprite_classes)) { $wptplx_sprite_classes = array( 'sprite-bubble-one', 'sprite-bubble-two', 'sprite-bubble-three', 'sprite-bubble-four', 'sprite-diamond-one', 'sprite-diamond-two', 'sprite-diamond-three', 'sprite-diamond-four', // Add your won custom sprite CSS classes here... // ... ); } return $wptplx_sprite_classes; }
This PHP code really only needs to decide which pages/posts should have parallax sprites enabled, then enqueue the JavaScript & CSS assets when needed. In wptplx_wp_enqueue_scripts()
you’ll see that we use get_post_meta() to check if there is a true/yes in the current post’s _parallax_sprites
post meta. If you’re not familiar with the standard PHP function filter_var(), you should check it out – it’s really useful for testing “yes”, “no”, “true”, “false” for boolean equivalence.
Next up, in your child theme’s main folder, open functions.php and add the following couple of lines:
// WPT Parallax Sprites require_once dirname(__FILE__) . '/wpt-parallax-sprites.php';
Create your Custom Field
Using Advanced Custom Fields (or Pods, or some other equivalent), create a custom field called “_parallax_sprites”, like this:
infoFor more information on creating a custom field, see our auto-numbered-headings tutorial. There’s a nice section on how to create a field using ACF.
When you’ve created the custom field, edit the post/page where you want parallax sprites and check the “_parallax_sprites” option.
Asset Files
There’s a bit more we need to do to finish scaffolding the project. In your custom child theme, create a new folder called “wpt-parallax-sprites”. Go into the folder and create two empty files, called “parallax-sprites.css” and “parallax-sprites.js”. We’ll populate the files later.
Finally, download the Rellax JS library file from the CDN and save it to your computer:
https://cdn.jsdelivr.net/gh/dixonandmoe/rellax@master/rellax.min.js
Copy the file into your child theme’s “wpt-parallax-sprites” folder so you end up with three files in there.
That’s the prep work done. Now we can start work on the JavaScript… getting it working in the browser.
The JavaScript Core
For our core functionality, open “wpt-parallax-sprites/parallax-sprites.js” and paste the following into it:
/** * WP Tutorials : Parallax Sprites (WPTPLX) * * https://wp-tutorials.tech/add-functionality/parallax-scrolling-sprites-with-rellax-js/ */ document.addEventListener('DOMContentLoaded', function() { 'use strict'; // Uncomment this for diagnostics // console.log('WPT Parallax Sprites : load'); if (typeof wptplxData === 'undefined') { console.log('ERROR: Missing the wptplxData object'); } else if (typeof Rellax === 'undefined') { console.log('ERROR: Missing the Rellax library'); } else { // Uncomment this for diagnostics // console.log('WPT Parallax Sprites : init'); var spriteClassCount = wptplxData.spriteClasses.length; var rootContainer = null; if (wptplxData.rootContainerSelector) { rootContainer = document.querySelector(wptplxData.rootContainerSelector); } // Fallback to using document.body as the root container. if (!rootContainer) { rootContainer = document.body; } var maxWidth = rootContainer.clientWidth; var maxHeight = rootContainer.clientHeight; // Exclude the sprites from the last 40% of the page. maxHeight = maxHeight * 0.60; var spriteIndex = 0; while (spriteIndex < wptplxData.spriteCount) { // Create the sprite's element, its container element and add the // sprite as a child of the container. const spriteContainer = document.createElement('div'); const sprite = document.createElement('div'); spriteContainer.append(sprite); spriteContainer.classList.add(wptplxData.containerClass); const left = Math.floor(Math.random() * maxWidth); const top = Math.floor(Math.random() * maxHeight); var speed = Math.floor(Math.random() * 9) - 4; spriteContainer.style.left = `${left}px`; spriteContainer.style.top = `${top}px`; spriteContainer.setAttribute('data-rellax-speed', speed); // Choose a random sprite class and add set it as our sprite's // CSS class. var spriteClassIndex = Math.floor(Math.random() * spriteClassCount); var spriteClass = wptplxData.spriteClasses[spriteClassIndex]; sprite.classList.add(spriteClass); // Add the sprite's container (and sprite) to our root container // (which is probably document.body) rootContainer.append(spriteContainer); ++spriteIndex; } // If we've created any sprites, we can initialise Rellax now. We don't // just pass the class name of the sprite containers, we need to put a // dot before it, because it's a selector. if (spriteIndex > 0) { wptplxData.rellax = new Rellax(`.${wptplxData.containerClass}`); } } });
The code breaks down like this:
- If
wptplxData
orRellax
are not defined, then…- report an error and don’t go any further
- Determine our root container element. This can be document.body, or any element on your page, such as
#content
or#main
- For each sprite that we need to create…
- Choose a random sprite type (CSS class) and store it in
spriteClass
.
- Create a
<div class="wptplx-sprite"></div>
element to act as our sprite’s container - Create a div for our sprite and set its CSS class to the value of
spriteClass
- Add the sprite div as a child of our sprite’s container div
- Set a random left and top position for our sprite’s container div
- Set a random speed for our sprite’s container div
- Add our sprite container to the root container
- Choose a random sprite type (CSS class) and store it in
- Initialise Rellax using the
.wptplx-sprite
selector
The sprites are rendered as two div elements, one inside the other. The outer element is a container element – this is what Rellax controls. The inner element is our actual sprite:
<div class="wptplx-sprite" data-rellax-speed="3" style="left: 12px; top: 34px;">
<div class="sprite-bubble-three"></div>
</div>
Before we can test the code, we need to add some CSS, so edit “wpt-parallax-sprites/parallax-sprites.css” and add this:
/** * WP Tutorials : Parallax Sprites (WPTPLX) * * https://wp-tutorials.tech/add-functionality/parallax-scrolling-sprites-with-rellax-js/ */ .wptplx-sprite { position: absolute; pointer-events: none; } .wptplx-sprite>div { width: 3em; height: 3em; } /** * Round bubbles */ .wptplx-sprite .sprite-bubble-one, .wptplx-sprite .sprite-bubble-two, .wptplx-sprite .sprite-bubble-three, .wptplx-sprite .sprite-bubble-four { border-radius: 50%; background-image: linear-gradient(to bottom right, white, transparent 30%); border: 1px solid lightblue; } .wptplx-sprite .sprite-bubble-one { border-color: lightblue; width: 7em; height: 7em; } .wptplx-sprite .sprite-bubble-two { border-color: lightgrey; width: 6em; height: 6em; } .wptplx-sprite .sprite-bubble-three { border-color: lightsteelblue; width: 5em; height: 5em; } .wptplx-sprite .sprite-bubble-four { border-color: lightcyan; width: 4em; height: 4em; } /** * Diamond bubbles */ .wptplx-sprite .sprite-diamond-one, .wptplx-sprite .sprite-diamond-two, .wptplx-sprite .sprite-diamond-three, .wptplx-sprite .sprite-diamond-four { border-radius: 1em; background-image: linear-gradient(to right, #fff8, transparent 20%); border: 1px solid lightblue; transform: rotate(45deg); } .wptplx-sprite .sprite-diamond-one { border-color: lightblue; width: 7em; height: 7em; } .wptplx-sprite .sprite-diamond-two { border-color: lightgrey; width: 6em; height: 6em; } .wptplx-sprite .sprite-diamond-three { border-color: lightsteelblue; width: 5em; height: 5em; } .wptplx-sprite .sprite-diamond-four { border-color: lightcyan; width: 4em; height: 4em; }
Analysis of the Logic
As with a lot of WordPress plugins/addons, we hook the wp_enqueue_scripts action to inject our CSS and JavaScript files into a page header. It’s important to pass the correct dependencies and version strings in wp_enqueue_script()
and wp_enqueue_style()
. Notice that when we enqueue our “wpt-parallax-sprites” scripts, we’re dependent on the “rellax” script being loaded first. Getting these dependencies correct will help your caching and asset aggregation system.
The JavaScript logic should be easy to read – it’s just a loop that puts a lot of DIVs all over the content, at random positions. And the CSS should be easy to hack into whatever shape you want too.
That’s it, really. Have fun with it 😎 👍