Share:

HTML Page Transitions

Date2018-08-31
Implement HTML page to page transitions - to produce the illusion of a self contained, connected entity.
VIEW DEMO

All we have is illusion

If you have an interest in UX on the web, you will know that consistency plays an important part in presenting the illusion that a webspace has legitimacy and trustworthiness. Consistency will also help to impart a sense of ownership over the virtual space the content occupies (in both virtual worlds - the web and our minds). I have always thought the main sticking point to creating consistency is the visual and subjective anarchy released every time a hyper-link is clicked - and we fly off (virtually) into the ether, to god knows where. Unless we are in a self contained App or SPA, we will always rely on the http application protocol (its not called HTML for nothing) - but maybe we don't have to visually convey this anarchy to the viewer. As usual, my research into finding ways of 'covering up the gap' ended at the first signs of anything remotely industry standard and the use of any external Libraries (if looking for that approach see here) what follows here is pure hacking away at the problem..

a diagram showing a process for html page to page transitions

Setting out the goals

The above illustration outlines the basic process. The aim is to get both the present page and the loading page to be identical, hiding the point when the new page is loaded. The easiest way to get two pages with different content to look the same is to make the whole screen a single colour. However, if you have a fixed navigation bar and you have only a few elements on your pages then another option is to 'morph' or move elements into places used on the loading page. This requires a lot more planing but does look and feel more fluid. You can even mix the two techinquies, using the fading method for individual complex areas of content.

Hijacking the links

So we need to allow some time to get the current page to a state when we can load the new page.

<a onclick="return endpagefake(this);"  href="page_1.html">
  Click Here
</a>

Every internal link on your site will need to call a javascript function via the onclick event, passing it a reference to itself (this is just the href value) using the this keyword. return simply means we can return a false value to cancel the actual link process. Add the following couple of functions to your javascript.

function endpagefake(passedLinkHREF){
    //we have to store the passed Link reference.
    //Store it in a globally defined variable.
    storeLinkHREF = passedLinkHREF;

    //now we will implement the change to the look of the page.
    //we add a class to the <BODY> tag in the html 
    //this will initiate the covering up of entire browser window
    document.getElementsByTagName('body')[0].classList.add('leavingPage');
  
    //now set up a timer to execute the actual link
    //You should wait until your cover animation stops
    window.setTimeout(actualendpage,1000);

    //returning false back to the link in the html will cancel it. 
    return false;   
}

function actualendpage(){
     //Now do the actual link
      window.location = storeLinkHREF;    
}

Using the Style Cascade

In the endpagefake() javascript function we added a class the HTML BODY tag, not directly onto the DIV that we want to use to cover up the page. This is good practise as you may also want to effect other elements when leaving the page. We only need target the BODY but by setting up styles in the CSS we can effect countless child elements. Here is the bare bones HTML:

<!DOCTYPE html>
    <head>
        <title>html-page-transitions :: Home</title>
    </head>
    <body class='no_scroll' onload="initialise();">
        <div class='cover_up'>
             <!-- can put logo here -->
        </div>
        <div class='content_wrapper'>
             <!--  page content here -->
             <a onclick='return endpagefake(this);' href='page-1.html'>
                Click for Page 1
             </a>
        </div>
     </body>
</html>

The DIV with the cover_up class will be used to cover the browser window, here is its basic CSS:

.cover_up{
    position: fixed;
    width:100%;
    height: 0px;
    top:0px;
    overflow:hidden;
    background-color: #c1c1c1;   
}

When we add the leavingPage style to the BODY tag, the element will now follow the following style declaration:

.leavingPage .cover_up{
     animation: fadeIn 0.3s ease-in;
     animation-fill-mode: forwards;
}

We have to use animation here as if we just transition the opacity up, the cover_up div will still stop the user activating the links, even at 0 opacity. (We could set the pointer-events style property to none) Here is the animation:

@keyframes fadeIn {
         0% {
               opacity: 0;
               height:0px;
          }
          1% {
               height:2000%;
          }
         100% {
               opacity: 1;
               height:2000%;
          }
}

The cover_up div lies in wait with height of 0px at the top of the browser. When the animation runs within the first frame its set to its set to a height which should cover the browser - but its still at zero opacity, so we can't see it yet. The opacity rises over the course of the animation thus completing the cover up.

On Load

We now have to make sure the new page loading matches this cover up state. Change the original .cover_up class to:

.cover_up{
    width:100%;
    height:2000%;
    position: fixed;
    top:0px;
    overflow:hidden;
    background-color: #c1c1c1;
    opacity:1;
}

This will load up the page with all the content covered up. To uncover, add a class of unload to the BODY tag in the initialise function in the javascript:

function initialise(){
    //set up the fade out
    document.getElementsByTagName('body')[0].classList.add('onload');
}

The animation is just a reverse of the fade-up animation. no_scroll refers to removing any scroll bars on the cover up screen, this is optional.

Dashed by the Cache

This works well in all browsers - if user is using the actual page links to navigate. At some stage though, users will start using the browsers own back and forward buttons to navigate through their current viewing session. Some browsers will just show cached versions of the pages already visited, rather than re-downloading the page. As we left our pages in a 'covered-up' state the browser will just show this to the user, with all the content hidden below the cover-up. Not very UX friendly. To combat this we use the onpageshow event to test if a page is cached (unload events won't be fired when cached pages are shown ).

In the javascript file create a global variable testonload, setting it to false. For the first page of your site the viewer views they have to use your internal page links to move away, so during the cover-up process we set testonload to true. When we come back to the page via caching, the onpageshow is fired and we test testonload, if true we can undo the cover-up routine. When not cached the onpageshow is still fired after unload event. So the final html BODY tag looks like:

<body class='no_scroll' onpageshow="testifcached();" onload="initialise();">

Adding the following to the javascript:

var testonload = false;
function actualendpage(){
     //reset browser cached test
     testonload = true;
     window.location = linkStored;   
}
function testifcached(){
      if (testonload){
           //page is browser cached  - firefox desktop, chrome ios?
          //undo our page cover up
          document.getElementsByTagName('body')[0].classList.remove('leavingPage');
     }
}
VIEW DEMO