Adding page transitions to WordPress
Recently I have worked on 2 projects where I have used WordPress with smoothstate.js, let’s find out how smoothstate.js can add page transitions to your website!
What is smoothstate.js?
“We’ve accepted the jankiness of page loads as a quirk of the web even though there is no technical reason for it. smoothState.js lets you add transitions to eliminate the hard cuts and white flashes of page loads that deface the beauty of the user experience.”
Miguel Ángel Pérez (author of smoothstate.js)
smoothstate.js is a Javascript library that allows you to load page content via AJAX, giving us more control over page transitions. It utilises HTML5’s pushState API which is widely supported by modern browsers. On older browsers, smoothstate.js is automatically disabled in the background and fallback to regular page load.
How I use smoothstate.js with WordPress
First include jQuery, then include smoothstate.js (you can download from https://github.com/miguel-perez/smoothState.js) into your site like so:
<script src="/your/path/to/jquery.js"></script>
<script src="/your/path/to/jquery.smoothState.js"></script>
Here is a basic example on how to setup all your pages. The idea is to have a container with the same id
on every page, initialise smoothstate.js on this container and everything inside the container will be replaced by data from AJAX call. Every URL on your site should return a full layout — not just an HTML fragment.
You can do something like this in your theme’s layout template:
<body>
<div class="loading-overlay"></div>
<div id="main" class="m-scene">
<div class="<?php echo $this['config']->get('body_classes'); ?>">
<div class="scene_element scene_element--fadein">
<!-- contents... -->
</div>
</div>
</div>
</body>
Together with the following CSS, anything inside .scene_element--fadein
will fade in once the page is loaded. You can also create your own keyframes or use other animation frameworks such as Animate.css.
/*
* CSS Animations
* Don't forget to add vendor prefixes!
* From: http://smoothstate.com/typical-implementation.html
*/
.m-scene .scene_element {
animation-duration: 0.25s;
transition-timing-function: ease-in;
animation-fill-mode: both;
}
.m-scene .scene_element--fadein {
animation-name: fadeIn;
}
.m-scene.is-exiting .scene_element {
animation-direction: alternate-reverse;
}
/*
* Keyframes
*/
@keyframes fadeIn {
0% { opacity: 0; }
100% { opacity: 1; }
}
Then in your own script file, you can initialise smoothstate with the following:
// From: http://smoothstate.com/typical-implementation.html
;(function($) {
'use strict';
var $body = $('html, body'),
content = $('#main').smoothState({
// Runs when a link has been activated
onStart: {
duration: 250, // Duration of our animation
render: function (url, $container) {
// toggleAnimationClass() is a public method
// for restarting css animations with a class
content.toggleAnimationClass('is-exiting');
// Scroll user to the top, this is very important, transition may not work without this
$body.animate({
scrollTop: 0
});
}
}
}).data('smoothState');
//.data('smoothState') makes public methods available
})(jQuery);
The above code essentially initialises smoothstate.js on your #main
div. When you click on any internal links, content inside #main
will be replaced by #main
on the next page. Duration
is telling the browser to wait until animation finish (250ms) before fetching the content on next page.
Notable options (full documentation):
- debug: if you are experiencing problems, you can turn
debug
on by setting it totrue
. Then smoothstate will log useful information to console. - blacklist: you don’t want to add transition to every link, for example you don’t want to use smoothstate for WordPress admin bar, dropdown links or images. You can easily blacklist them using the jQuery selector:
blacklist: ".no-smoothstate, .post-edit-link, a[href*='.jpg'], a[href*='.png'], a[href*='.jpeg'], a[href*='.pdf']"
Add loading screen between transitions
Fetching data often takes much longer than the animation. Having user staring at a blank screen will lead to panics and frustrations. Adding a loading overlay lets users know that the website is still loading. It also acts as a cover for any screen flickering or abnormal behaviour caused by the animations.
The following is a very simple example that fades in an overlay during onStart
function and then fades out the overlay inside onAfter
function.
;(function($) {
'use strict';
var $body = $('html, body'),
content = $('#main').smoothState({
// Runs when a link has been activated
onStart: {
duration: 250, // Duration of our animation
render: function (url, $container) {
// toggleAnimationClass() is a public method
// for restarting css animations with a class
content.toggleAnimationClass('is-exiting');
// loading overlay starts fading in after 250ms
$('.loading-overlay').fadeOut();
// Scroll user to the top, this is very important, transition may not work without this
$body.animate({
scrollTop: 0
});
}
},
// runs when the new content has been injected into the page and all animations are complete
onAfter: function($container, $newContent) {
// once content has loaded, loading overlay can fade out
$('.loading-overlay').fadeOut();
}
}).data('smoothState');
//.data('smoothState') makes public methods available
})(jQuery);
Potential issues
If you have plugins that initialise on page load (e.g. inside $(document).ready()
), you will have to initialise again in onAfter
. That is because smoothstate.js is not reloading the page, it is just replacing content within the page and therefore anything inside $(document).ready()
will not run again.
Parting words
And there you have it, this is just a very simple tutorial on how to implement smoothstate.js into your WordPress site. There are so many more possibilities, you just have to be creative!
Be sure to checkout the work we did using smoothstate.js with WordPress!