In the previous tutorial, we’ve covered how to create some cool page transitions using Barba.js and the CSS plugin. Today we will break down some the of terms associated with Barbas page transitions logic.
This will help you to trigger the right transition at the right time.
Include @barba/core, @barba/css plugin in your JavaScript module, and tell Barba to use the CSS plugin.
// install via npm or yarn
npm install @barba/core @barba/css
yarn add @barba/core @barba/css
// Include Barba and Barba CSS in your project
import barba from '@barba/core';
import barbaCss from '@barba/css';
// Tell Barba to use the CSS plugin
barba.use(barbaCss);
// Initiate Barba
barba.init();
<body data-barba="wrapper">
<!-- content that stays the same on all pages - eg. header -->
<div data-barba="container">
<!-- content that will change from page to page -->
</div>
<!-- content that stays the same on all pages - eg. footer -->
</div>
Barba.js will now add and remove specific CSS classes from the data-barba="container".
These CSS classes will be based on the transitions that we need to specify.
If you are completely new to Barba.js, you can check this tutorial to learn more about the required HTML markup.
How to create fade-in transition on page load
To create a simple fade in transition on page load we can use the once hook.
barba.init({
transitions: [
{
once() {}
}
]
});
Barba.js will add and remove the following CSS classes .barba-once, .barba-once-active and .barba-once-to during the transition.
.barba-once and .barba-once-active will be applied at the start of the transition.
.barba-once-active and .barba-once-to will be applied during the transition.
This hook is called once, because this transition only runs once on the page load.
When the CSS transition is completed, all CSS classes will be removed from the container.
How long these classes stay on the container depends on the duration of the CSS transition or animation.
Because the CSS plugin overrides the main once hook, any code inside of once will be ignored. The same applies to the enter and leave hooks.
barba.init({
transitions: [
{
once() {
console.log('this will be ignored');
},
beforeOnce() {
console.log('shows up BEFORE once transition');
},
afterOnce() {
console.log('shows up AFTER once transition');
}
}
]
});
If you need to run any code related to the once transition use beforeOnce or afterOnce hooks.
How to customize the name of the CSS class?
You can customize the CSS classes by specifying a name for your transition.
transitions: [
{
name: "home",
once() {}
}
]
If you specify home as the name, Barba will generate these classes:
.home-once
.home-once-active
.home-once-to
The format of the class is always the same: .[name]-[hook]-[state].
How to create CSS transition between two pages
Every page transition has two phases.
Firstly the current page leaves, then the next page enters.
To use CSS transitions between two pages, we need to specify the hooks inside of the Barba transition, even if there is no code inside of them.
Perfect, this was a simple fade transition, but what if wanted to make a transition where both containers are visible on the page? How would we do that with Barba.js?
Let’s see in the next example.
How to create clip-path transition
Now that you know the basics of Barba.js and the CSS plugin, only your imagination is your limit!
In the next example, we will try to reveal the next page from the center of the screen.
We will clip the incoming page clip-path: circle(0%); at the start and reveal it by specifying clip-path: circle(75%); as the end of the transition.
For this effect, we need to have both containers on the page and Barba has a sync mode build-in exactly for that.
This is a simple full-screen element covering the whole viewport, by default it is positioned outside of the viewport using transform: translateY(-100%);.
In the first phase, we are transitioning the .transition element to translateY(0) using the .with-cover-leave-to .transition selector. This is also the starting position for the enter animation.
Then we are moving the .transition out of the viewport to transform: translateY(100%); using the .with-cover-enter-to .transition selector.
As you can see, the stylesheet could grow quite quickly.
At the start of the transition, we are using .slide-enter CSS class to position the incoming next page outside of the viewport.
Then we are animating both containers by 100%. The current page goes away from the viewport to translateX(100%) and the next page moves to translateX(0).
The page entering the viewport is positioned absolute during the transition as we have defined in the .slide-enter-to CSS class.
And that is it, now you have learned how to create 4 different page transitions using Barba.js and the CSS Plugin.
After a long time in making, I am very excited to announce that the new lineup of my premium online courses will be available for purchase from the 18th of August 2020.
What is Practical GreenSock?
Practical GreenSock is a bundle of 3 online courses teaching you how to create more advanced animations and effects using GreenSock, ScrollTrigger and vanilla JavaScript.
All 3 courses are suitable for intermediate to advanced developers and designers.
Here is the breakdown of all 3 courses included in Practical GreenSock, watch the first unit from each of them to learn more.
We import useState, set the default color and create a functiontoggleBackground that will toggle the background color between light and dark.
Then inside of a new useEffect that only listens to the background color change, we are using GreenSock’s .to tween to animate the background-color to the right value.
Please excuse my non-creative animations today, I am trying to keep the example as simple as possible.
5. How to create an array of refs
ScrollTrigger is the cool plugin from GreenSock that lets you trigger animations as the user scrolls through your page.
Let have a look how to include ScrollTrigger in your React project and fade in a few section.
We have two transitions leave() and enter(), but this time we are passing trigger to the loaderIn function and next to the loaderAway function.
How to scale up from where the user clicked
Each Barba.js hook receives the same data argument that contains the current and next page properties, it also includes trigger that is the link that triggered the transition.
function loaderIn(trigger) {
// get the size of the clicked trigger element
const { height, width, top, left } = trigger.getBoundingClientRect();
const triggerTop = Math.floor(top);
const triggerLeft = Math.floor(left);
const triggerWidth = Math.floor(width);
const triggerHeight = Math.floor(height);
// get viewport size, this will be used for scaling up the loader
const viewportHeight = window.innerHeight;
const viewportWidth = window.innerWidth;
const loaderSize = viewportHeight > viewportWidth ? viewportHeight*2 : viewportWidth*2;
...
}
We are firstly getting the dimensions of the trigger and its top and left offset relative to the viewport using the javascript getBoundingClientRect() method.
Secondly, we are getting the size of the viewport to be able to resize the loader accordingly.
Because the loader will always scale up from the center of the clicked element we need to make sure it is twice the size of the viewport.
How to use GreenSock for page transitions
Now we need to create a GreenSock timeline that will scale the loader up.
Remember Barba.js only replaces the content of the data-barba="container”. This means that the body class would stay the same when navigating between the pages.
We have to manually update it like this:
function loaderAway(next) {
document.body.removeAttribute('class');
document.body.classList.add(next.container.dataset.class);
...
}
We are passing the next page to the loaderAway(next) function.
Inside of it, we are firstly removing the class attribute from the body tag and then applying the class that we have defined on the incoming page container as data-class="is-page-2”.
This will make sure that the body class is updated before we reveal the incoming page.
Reveal the new page
Now we have the whole page covered by the scaled-up loader, Barba updated the page under the loader and we are ready to reveal it.
The loader is a simple div, with a border-radius set to 100% to appear as a circle.
And that is it, now you know how to create a circular page transition using Barba.js and GreenSock. If you are new to GreenSock, checkout GreenSock 101 where you can learn even more about this powerful animation library.
Have you seen any cool page transitions that you would like to see covered in my future page transitions tutorial?
We will make it position: fixed and the height twice as tall as the screenheight: 200vh. This is because we will soon be slightly rotating it. Without any rotation a height: 100vh would be enough to cover the whole screen.
Opacity and visiblity are set to 0 and hidden, because we don’t want to see a flash of the loader before GSAP scales it down.
// reset position of the loading screen
gsap.set(loader, {
scaleX: 0,
rotation: 10,
xPercent: -5,
yPercent: -50,
transformOrigin: 'left center',
autoAlpha: 1
});
In the main.js we are rotating the loader and setting the scaleX to 0 to make it invisible for the user. At the same time we are setting visibility: visible and opacity: 1 using GreenSock’s handy autoAlpha property.
2. Include Barba.js
Include Barba.js at the bottom of both HTML files.
I am also including GreenSock because Barba.js is not an animation library – it only takes care of content loading.
Your preferred animation library and style of page transition is completely up to you.
I tend to choose GreenSock for its flexibility and easy functionality. I have also become very familiar with it.
If you want to learn how to use GreenSock from scratch, check out GreenSock 101.
There are plenty of other animation libraries that would also work well, such as popmotion, animejs, mojs or spirit.
3. HTML Markup
Barba.js requires two special data-attributes somewhere in your markup.
<body data-barba="wrapper">
<!-- content that stays the same on all pages - eg. header -->
<div id="intro" data-barba="container">
<!-- content that will change from page to page -->
</div>
<!-- content that stays the same on all pages - eg. footer -->
</div>
data-barba="wrapper" specifies the main wrapper of your page structure. This could be in the body or any other HTML element.
data-barba="container" is a section of your page which will be “reloaded or updated,” with the incoming content from the other page.
Anything outside of the containerwill not change between the page transitions.
You can use any markup you want, the only requirement is that the wrapperalways needs to wrap the container.
One common example would be to add css class to your page to prevent users from double clicking on links.
// do something before the transition starts
barba.hooks.before(() => {
document.querySelector('html').classList.add('is-transitioning');
});
// do something after the transition finishes
barba.hooks.after(() => {
document.querySelector('html').classList.remove('is-transitioning');
});
This may have been just a basic example, however I hope you can now see implementing page transitions can be a simple task!
The ultimate key is to master Barba.js and an animation library of your choice. If you’d like to go with GreenSock, learn everything you’ll need to know at GreenSock 101.
Today we really only scratched the surface of page transitions. It is a broad area, with lots of creative options out there.
So, if you have you seen other interesting page transitions you would like to learn about, please let me know! I’d be happy to make more in-depth page transition tutorials.