Page Transitions for Everyone

Avatar of Georgy Marchuk
Georgy Marchuk on

As Sarah mentioned in her previous post about page transition using Vue.js, there is plenty of motivation for designers and developers to be building page transitions. Let’s consider mobile applications. While mobile applications are evolving, more and more attention is given to the animation experience, while the web pretty much stays the same. Why is that?

Maybe it’s because native app developers spend more time working on those animations. Maybe it’s because users say that’s what they want. Maybe it’s because they know more about the environment in which the app is going to run. All of that helps to improve the experience over time. Overall, it seems like mobile app developers somehow seem to know or care more about user experience.

If we take a look at how mobile apps are designed today, there is very often some sort of animated transition between states. Even ready-to-use native components have some kind of simple animation between states. Developers and designers realized that this little animation helps a user grasp what is happening in the app. It makes the navigation through the app easier and tells the user where they are going within the app.

For example, when you’re navigating to a subcategory, it usually slides in from the right side of the screen, and we all somehow know what that means.

Animation matters. It can be used to improve the user experience.

When you’re developing a website, it’s easy to spend hours making sure the user sees the whole story by way of top-notch transitions, like the movement between gallery pictures or fancy hover effects…but once a user clicks a link, all of that experience falls apart and you’re starting from the beginning. That’s because the page reloads and we don’t have an easy/obvious/native way to handle animations/transitions in that situation.

On the web, most of the effort used to improve the experience is in structure, visual design, or even the performance of the site. There are some elements you can swipe around here and there, but that’s about it. A boring remnant of the time when the web was simply used to navigate through a bunch of text pages later upgraded with some sliding text.

Yes, we actually used to do this.

There are some very fancy websites that are filled with animation or incredible WebGL hieroglyphs in the background. Unfortunately, they are often hard to navigate and your laptop battery is drained in about 15 minutes. But they are certainly nice to look at. Those sites are full animation, but most of it is used to impress you, and not to help you navigate around, or make the experience faster, or make things more accessible for you to browse the site.

The Source of the Problem

All of this raises a big question. We have all the technology to do this page transitions stuff on the web. Why don’t we do it? Is it because we don’t want to? Is it because we don’t think that’s part of our job? Is it so hard that we’d have to charge double for projects and clients aren’t buying it?

Let’s take a look at another possible reason. Often, a company chooses technologies that are common for all of their projects. You, as a front-ender, don’t have much control over what’s implemented on the server, so maybe you can’t count on some server-side rendering of your JSX.

Maybe you have to choose something stable and generally usable for any sort of solution (which usually means the less codebase, the more flexible), so you’re kind of forced to avoid some framework in your development stack. Unfortunately, it makes sense. You don’t want to implement a contact form in 10 different frameworks just because you’ve decided that some framework is a good base for this particular project. And don’t get me started on security, which has been in the process of being improved throughout the years. You cannot just throw it away because you want your user to have a bit more fun browsing your site.

There is another possible reason. Maybe you want to build on WordPress because you want to take advantage of all those open source goodies people prepared for you over the years. Would you exchange all of that “free” functionality for a better experience? Probably not…

The Goal

Aside from drastic and unrealistic changes like getting rid of all images and videos, our website load time from the server just is what it is. We have a server rendered page, and apart from a faster server or better caching, there isn’t much to do to improve that.

So the way to improve the load time is to cheat a bit! Cheat by making the user think it takes less time because they are distracted by what’s happening on the screen. Cheat by loading the content ahead of time and animating the transition.

Let’s introduce some effects that could be used to do the transition. Even simple fade in/fade out can give you a whole different feel, especially with some element indicating loading. Let’s look at some examples.

Note: All of following examples are websites build on PHP and pretty much work without JavaScript as any other site would.

Source: (public production site)

A simple fade out/fade in seamlessly improves experience user has before the click of the link and doesn’t act that disturbing as a normal browser reload would. The loading indication on a menu icon ensures a user doesn’t panic in case the page takes little longer to load.

Some interesting animation can be achieved by animating different elements in different ways, which can also be combined with fading.

Source: (public production site)

Or how about covering up the page with some other element?

Source: (public production site)

Those few hours of work give the website whole new feel by turning your static page into an animated one. And that’s without any additional preparation.

However, in case you are already aware of your intention in the design phase, you can adjust the design to your needs. Common elements can be prepared ahead of time.

Source: (company internal system)

The main navigation element introduced in a form of bubbles plays with the user while the content of the next page is loading. The impact is that user is not bored and knows that something is happening. As the animation starts on the click of the link, the user doesn’t even realize he’s been waiting for something.


We have sorted out what we actually want to do, and why do we want to do it… let’s see how can we achieve this.

While there is not much to do on the back-end for this, there is a whole bunch of things you can do on the browser side. A good example is Turbolinks, developed by the Basecamp folks, which takes your website and makes it more app-feeling by enabling content loading with JavaScript. It simply avoids that ugly browser page-to-page reloading jump. Turbolinks deals with browser history, loading, and all that other stuff that would normally happen under the hood of the browser. The key thing here is taking control over loading and replacing content because as long as the browser doesn’t reload, everything that happens on a screen is in our control.

Let’s think of some concepts we can use to improve our experience. The load time is our biggest enemy, so how can we improve it in the browser?


In most cases, the request for loading the next page doesn’t have to start only once a user clicks the link. There is another event happening that can indicate users intention to visit the page, and that’s a hover over the link. There are always few hundreds of milliseconds between hover and click on the link, why not use that time to our advantage? Heck, if the majority of your users end up on the next page that is known to you and you have the statistics to prove it, why not even preload it any time after the initial render, while the user is trying to get around the current page?

The following diagram illustrates how many things can happen in parallel and save us some of that precious time, instead of being done one by one. A very common mistake seen in custom solutions for page transition that people make for themselves is the start of the request, which is usually triggered after the page is unloaded/hidden.

Possible process of transition


While this can be a problem for some dynamic sites, static sites are perfect candidates for caching. Why would you load a page twice, when you’re in control of loading and replacing the content? You can save the contents and use it in case the user visits the same page or returns to it with the browser back button.

Or, you can use the cache to preload pages on hover and empty the cache regularly (maybe after each page visit?) to always have the latest version of the page on dynamic sites while still enabling that preload feature.

Interestingly, Progressive Web Apps also “invest” in this area, although the approach is a bit different.


All these concepts are great, but we still need to bring animations to the party.

The control of the page load and replacement can be taken over by us, thus we can play with the contents of the page at any given time. For example, it’s simple enough to add a class to the page while it’s loading. This gives us the ability to define another state for the page, or in other words, hide/unload it. When the animation is done and the page is loaded, we are free to replace the content and remove the state class to let the page animate back in again.

Another option is to animate your page “out” with JavaScript, replace the content, and animate it back “in.”

There are many possibilities of how to approach this, but in any way, the key feature here is not letting the browser reload.

Ready to Go

Those are three main concepts that will make a lot of difference. The point is, with a little extra effort, it’s not that hard to do this yourself, and I encourage you to do so.

It’s going to be a bumpy road with loads of possible headaches, as it’s not always easy not to break the browser’s native functionality.

However, if you’re more of a load and go type of person, I have put together a little package called swup that sorts out all of those things that Turbolinks does, plus all three of the concepts we’ve covered here. Here’s a little demo.

What are the perks of swup?

  • It works exclusively on the front-end, so no server setup is required. Although you can easily implement a transfer of only required data based on X-Requested-With in the request header (little modification of swup is required based on your particular solution).
  • Uses browser history API to ensure correct functionality of your site, as it would work without swup (back/forward buttons and correct route in the URL bar).
  • It does not have to be part of initial load batch and can be loaded and enabled after the initial render.
  • Takes care of the timing, meaning it automatically detects the end of your transitions defined in CSS and, in the meantime, takes care of loading the next page. The whole process is based on promises, so not a single millisecond is wasted.
  • If enabled in options, swup can preload a page when a link is hovered or once it’s encountered in loaded content (with the data-swup-preload attribute).
  • If enabled in options, swup also caches the contents of the pages and doesn’t load the same page twice.
  • Swup emits a whole bunch of events that you can use in your code to enable your JavaScript, analytics, etc.
  • You can define as many elements to be replaced as you want, as long as they are common for all pages. This enables the possibility to animate common elements on the page, while still replacing its parts. The bubble menu in our earlier example above uses this feature, where the check signs on the bubbles are taken from the loaded page, but rest of the bubble stays on the page, so it can be animated.
  • Gives you the possibility to use different animation for transitions between different pages.

For those of you that like your animation done with JavaScript, there is also a version for that called swupjs. While it may be harder to implement animations in JavaScript, it definitely gives you more control.


The animation and seamless experience doesn’t have to be strictly limited to native applications or newest technologies. With little effort, time, and a bit of code, even your WordPress site can feel native-like. And while we already love the web the way it is, I think we can always try to make it a little better.