News

Design a scrolling progress page with HTML5

Keep users’ attention on content instead of wondering about the length of the article

14

Have you ever started reading an article only to be distracted by wondering about how much more there is read? This not knowing is one of the reasons users often cite for abandoning a page, or even the whole website. The act of breaking off from reading to take a look at how much more content there is obviously disrupts the user experience, and it’s all too easy to lose your place and decide to give up on the content entirely.

Award-winning news site, The Daily Beast (www.thedailybeast.com), has developed an innovative sidebar that they call the ‘READ THIS.list’. The secret to its success is in the multiple functionalities it provides. First, it is a list of all the articles on the page, each one just a click away.

The sidebar indicates which article you are currently scrolled to but, most interestingly, it shows your progress through the article by way of a progress bar that fills from left to right as you scroll down. Simple really, and very intuitive for the user, with no instructions required to explain its use. In this tutorial you’ll learn how to emulate this feature and design your own menu for showing progress through a story.

Start with the HTML

This tutorial provides enough explanation for you to integrate the technique in your own projects, however, the progress bar element is HTML5 technology so do keep that in mind if you need to cater for older browsers. We’re declaring the HTML5 doctype, linking to the stylesheet, a copy of jQuery and the jQuery plug-in.

001 <!DOCTYPE html>
002 <html lang=”en”>
003 <head>
004 <meta charset=”utf-8”>
005 <title>2BR02B by Kurt Vonnegut</title>
006 <link href=”resources/style.css” 
rel=”stylesheet”>
007 <script src=”resources/jquery.js”></script>
008 <script src=”resources/scrollnavprogress.
js”></script>
009 </head>

The progress bar values

Several variables are created when the page is loaded. ‘top’ for the current vertical scroll position, ‘sheight’ the total height of the page. Sections are given their own progress bar and offsets are worked out (using trial and error -4, -90, -160, -210). These offsets determine when each progress bar starts incrementing.

001 $(document).ready(function () {
002     $(window).scroll(function () {
003             var top = $(this).scrollTop(),
004                     sheight = $(document).height(),
005                     scrll = (top / sheight);
006             $(“#progress_bar1”).attr(‘value’, 
((scrll)*300)-4);
007             $(“#progress_bar2”).attr(‘value’, 
((scrll)*300)-90);
008             $(“#progress_bar3”).attr(‘value’, 
((scrll)*300)-160);
009             $(“#progress_bar4”).attr(‘value’, 
((scrll)*300)-210);
010         });
011 });

Set maximum values

The max parameter for each progress bar is adjusted so that each bar is just filled as the end of its section scrolls out of the top of the viewport. A more sophisticated solution could be developed that dynamically creates the menu based on headings and their position within the document.

001 <div id=”main”>
002         <div id=”sidebar”>
003             <div class=”menu”>
004                 <a href=”#top”><img     src=”resources/phone.png” alt=””></a>
005                 <progress id=”progress_bar1” 
value=”0” max=”84”></progress>
<a href=”#partone”><h4 class=”caption”>Part
One</h4></a>
<p class=”subtitle”>Everything was... </p>
006     <progress id=”progress_bar2” value=”0”
max=”67”></progress><a href=”#parttwo”><h4
class=”caption”>Part Two</h4></a><p
class=”subtitle”>The painter thumbed his 
nose</p>

Content anchoring

Moving from the latest HTML5 functionality back to possibly the oldest, simplest and arguably the most important HTML code, anchor tags are added here to enable the menu to provide one click access to any of the story sections. Code in the plug-in enables the animated scrolling to these sections.

001 <div id=”content”>
002 <a name=”partone”> </a>
<p>Everything was ...</p>
003 <a name=”parttwo”>
<hr style=”width: 100%;”></a>
004 <a name=”partthree”>
<hr style=”width: 100%;”></a>
005 <a name=”partfour”>
<hr style=”width: 100%;”></a>
006 </div>

This is the end

After the footer, a plug-in function is executed that determines the positioning of the sidebar. In this tutorial, once the header scrolled away, the sidebar menu is fixed at 10px below the page top until the last 250px of the page is reached, when it is unlocked and free to scroll again.

001 <script>
002 (function($) {
003     $.lockfixed(“#sidebar .menu”,{offset: 
{top: 10, bottom: 250}});
004 })(jQuery); 
005 </script>

The CSS

The purpose of the technique is to make your content easy to digest, but it’s important to consider how your styling decisions will impact on usability too. Take time to experiment a little with your CSS and keep reviewing your layouts to see if improvements can be made.

001 @import url(http://fonts.googleapis.com/
css?family=Rokkitt:400,700);
002 body {
003     padding: 50px;
004     background-color: #eef4ee;
005     font-family: ‘Rokkitt’, serif;
006 }
007 h1,h2,h3,h5,h6 {
008     color: #da0933;
009     margin: 0 0 20px;
010     line-height: 1.1;
011     font-weight: 700;
012 }
013

Shorthand properties syntax

The paragraph margins here are an example of a shorthand properties tag. 1 and 4 value syntax is easy to guess (1 value = all values equal, 4 values = each value as specified), but what’s the rule for 2 and 3 value syntaxes? Where 2 values are provided the first value represents the top and bottom, the second value represents the right and left edges. With 3 values, the first value is the top, second value right and left, and third value, the bottom.

001 p {
002    margin: 0 0 20px;
003    color: #777;
004    font-size: 22px;
005    font-weight: 400;
006 }

Start at the top

The #head is where you’ll often put your primary navigation, but in this case it just holds the heading and a little divider. This content will then disappear when you scroll up, so any content that you want to be ‘persistent’ will need to go into the sidebar.

001     h1 {
002    font-size: 60px;
003 }
004 a {
005    color: #da0933;
006    text-decoration: none;
007 }
008 #head {
009    width: 100%;
010    border-bottom: 1px solid #CED5E5;
011 }

Should I stay or should I go?

The #main <div> is going so it is given a position: relative; but the #sidebar is staying and has a position: absolute; property. While it is given a top value of ‘0’, there is some code at the bottom of the HTML where offsets are added so the content scrolls up to the offset point and stays there until the bottom offset point comes in to effect.

001     #main {
002    position: relative;
003 }
004 #sidebar {
005    width: 280px;
006    position: absolute;
007    left: 0;
008    top: 0;
009 }

Moving on up

You could remove the width property for the content and still achieve a relatively accurate responsive layout. However, if responsiveness is important to you, you will need to work on binding the start and stop points of the progress bars to actual element position in the DOM, rather than using fixed calculation based on observed positions during the page design.

001     #content {
002    margin-left: 250px;
003    top: 0;
004    border-left: 1px solid #CED5E5;
005    width: 600px;
006    padding: 10px;
007 }

Bottoms up

Ensure the height enables the display of all your footer content and adjust the bottom offset specified at the bottom of the HTML to suit. Too large an offset in relation to the footer height and the sidebar will move off the page prematurely at the page bottom. Too small and the footer will crash into the sidebar.

001     #footer {
002    height: 180px;
003    border-top: 1px solid #CED5E5;
004    padding: 10px;
005    font-size: 18px;
006 }

Fit for purpose

When determining the width of your sidebar menu, consider how much space you will need to create meaningful navigation labels for your content. You don’t want to find yourself with too little space, but equally you shouldn’t steal too much space from the main content area – the content comes first after all.

001 .menu {
002    margin: 15px 5px 0 0;
003    padding: 2px;
004    position: static;
005    top: auto;
006    width: 235px;

Navigation labels

The large negative top margin of the .caption positions this content on top of the progress bars. If you change the progress bar height or the size of the .caption or .subtitle text, you may need to adjust this top margin and the bottom .subtitle margin to position the text on the progress bar as you wish. Make sure the text colours you choose work well with the filled and unfilled bar colours.

001        .caption {
002    text-transform: uppercase;
003    margin: -55px 0 0 5px;
004    font-size: 22px;
005 }
006 .subtitle {
007    margin: 0 0 25px 5px;
008    font-size: 17px;
009    color: #eee;
010 }



Style the progress

The default appearances (which are difference in each browser) are stripped away to give us a reasonable starting point to work with. It is worth drawing attention to a difference between Mozilla and WebKit browsers here. With Mozilla, the background to the progress bar isn’t prefixed, it’s specified as part of the simple ‘progress’ property and the ‘slidey-bit’ is prefixed and known as the progress-bar.

001     progress {
002    -webkit-appearance: none;
003    -moz-appearance: none;
004    appearance: none;
005    border: 0;
006    height: 60px;
007    width: 229px;
008    background-color: #aeceaf;
009 }

Bars and values

In WebKit browsers both elements are prefixed, the progress-bar is the background element though and this time the ‘slidey-bit’ is known as the progress-value. Don’t worry, it’s not unusual for your values to become confused when there are number of bars involved!

001 progress::-moz-progress-bar {
002    background-color: #000;
003 }
004 progress::-webkit-progress-bar {
005    background-color: #aeceaf;
006 }
007 progress::-webkit-progress-value {
008    background-color: #000;
009 } 



Border box fix

The border box fix is used to improve consistency across the browsers. Paul Irish (bit.ly/1bOCe3b) and Chris Coyier (bit.ly/1l1q1Lq) both offer detailed explanations of this issue, which are definitely worth a read. The fix ensures that the formatting of elements is handled consistently on the page by adding borders and padding inside them rather than adding to their size.

001     div {
002    -webkit-box-sizing: border-box;
003    -moz-box-sizing: border-box;
004    box-sizing: border-box;
005 }



Prevent a crash

To avoid having the footer crash into the locked sidebar, it is unlocked if the offset value specified in the bottom of the HTML is reached and will scroll neatly up the page. You’ll need to adjust the offset in conjunction with the #footer height to achieve a pixel-perfect result.

×