Adding Interactivity and Completing Your Site

Divya Manian

December 2012

(For more resources related to this topic, see here.)

Using jQuery

HTML5 Boilerplate provides a handy and safe way to load jQuery. With jQuery, it is vastly simple to work on writing scripts to access elements.

If you are writing custom jQuery script either to kick off a plugin you are using or to do some small interaction, put it in the main.js file in the js folder.

Using other libraries

If you are more comfortable using other libraries, you can also load and use them in a similar way to jQuery.

The following is how we load jQuery:

<script src="// js"></script> <script>window.jQuery || document.write('<script src="js/vendor/ jquery-1.8.2.min.js"><\/script>') </script>

Let us say, you want to use another library (like MooTools ), then look up the Google Libraries API to see if that library is available at If it is available, just replace the reference with the appropriate reference from the site. For example, if we want to replace our jQuery link with a link to MooTools, we would simply replace the following code:

<script src="// js"> </script>

With the following line of code:

<script src=" compressed.js"> </script>

We will also download Mootools' minified file to the js/vendor folder locally and replace the following code:

<script>window.jQuery||document.write('<script src="js/vendor/jquery- 1.7.2.min.js"><\/script>') </script>

With the following line of code:

<script>window.jQuery||document.write('<script src="js/vendor/ mootools-core-1.4.5-full-compat-yc.js"><\/script>') </script>

Adding smooth-scroll plugin and interaction

If you have not noticed it already, the website we are building is a single page site! All content that is required is found on the same page. The way our site is currently designed, it would mean clicking on one of the site navigation links would scroll roughly to the section that the navigation link refers to. We would like this interaction to be smooth. Let us use jQuery's smooth-scroll plugin to provide this.

Let us download the plugin file from the Github repository, hosted on

In it, we find a minimized version of the plugin (jquery.smooth-scroll.min.js) that we shall open in our text editor.

Then copy all the code and paste it within the plugins.js file.

Let us add a class name js-scrollitem to let us distinguish that this element has a script that will be used on those elements. This way, there will be a lesser chance of accidentally deleting class names that are required for interactions prompted via JavaScript.

Now, we shall write the code to invoke this plugin in the main.js file. Open the main.js file in your text editor and type:


This will make all the clickable links that link to sections on the same page within the parent container with class js-scrollitem scroll smoothly with the help of the plugin. If we have used our HTML5 Boilerplate defaults correctly, adding this will be more than sufficient to get started with smooth scrolling.

Next, we would like the navigation links in the line up section to open the right-hand side line up depending on which day was clicked on. Right now, in the following screenshot, it simply shows the line up for the first day, and does not do anything else:

Let us continue editing the main.js file and add in the code that would enable this.

First, let's add the class names that we will use to control the styling, and the hiding/showing behavior within our code. The code for this functionality is as follows:

<nav class="t-tab__nav"> <a class="t-tab__navitem--active t-tab__navitemjs-tabitem" href="#day- 1">Day 1</a> <a class="t-tab__navitemjs-tabitem" href="#day-2">Day 2</a> </nav>

Now, we shall write the code that will show the element we clicked on. This code is as follows:

var $navlinks = $('#lineup .js-tabitem'); var $tabs = $('.t-tab__body'); var hiddenClass = 'hidden'; var activeClass = 't-tab__navitem--active'; $ { // our code for showing or hiding the current day's line up $(this.hash).removeClass(hiddenClass); });

By checking how we have done so far, we notice it keeps each day's line up always visible and does not hide them once done! Let us add that too, as shown in the following code snippet:

var $navlinks = $('#lineup .js-tabitem'); var $tabs = $('.t-tab__body'); var hiddenClass = 'hidden'; var activeClass = 't-tab__navitem--active'; var $lastactivetab = null; $ { var $this = $(this); //take note of what was the immediately previous tab and tab nav that was active $lastactivetab = $lastactivetab || $tabs.not('.' + hiddenClass); // our code for showing or hiding the current day's line up $lastactivetab.addClass(hiddenClass); $(this.hash).removeClass(hiddenClass); $lastactivetab = $(this.hash); return false; }

You would notice that the active tab navigation item still seems to suggest it is Day 1! Let us fix that by changing our code to do something similar with the tabbed navigation anchors, as shown in the following code snippet:

var $navlinks = $('#lineup .js-tabitem'); var $tabs = $('.t-tab__body'); var hiddenClass = 'hidden'; var activeClass = 't-tab__navitem--active'; var $lastactivetab = null; var $lastactivenav = null; $ { var $this = $(this); //take note of what was the immediately previous tab and tab nav that was active $lastactivetab = $lastactivetab || $tabs.not('.' + hiddenClass); $lastactivenav = $lastactivenav || $navlinks.filter('.' + activeClass); // our code for showing or hiding the current day's line up $lastactivetab.addClass(hiddenClass); $(this.hash).removeClass(hiddenClass); $lastactivetab = $(this.hash); // change active navigation item $lastactivenav.removeClass(activeClass); $this.addClass(activeClass); $lastactivenav = $this; return false; });

Bingo! We have our day-by-day line up ready. We now need to ensure our Google Maps iframe renders when users click on the Locate on a map link. We also want to use the same link to hide the map if the users want to do so.

First, we add some identifiable features to the anchor element used to trigger the showing/hiding of map and the iframe for the maps, as shown in the following code snippet:

<p>The festival will be held on the beautiful beaches of NgorTerrou
Bi in Dakar.
<ahref="#" class="js-map-link">Locate it on a map</a>
<iframe id="venue-map" class="hidden" width="425"
height="350" frameborder="0" scrolling="no" marginheight="0"
marginwidth="0" src="

Then we use the following JavaScript to trigger the link:

$maplink = $('.js-map-link'); $maplinkText = $maplink.text(); $maplink.toggle(function() { $('#venue-map').removeClass(hiddenClass); $maplink.text('Hide Map'); }, function() { $('#venue-map').addClass(hiddenClass); $maplink.text($maplinkText); });

Now, let us look at how we can make our audio player work on all browsers.

Adding HTML5 features safely with Modernizr

It is highly recommended that we create a custom build of Modernizr. HTML5 Boilerplate comes with a custom build of Modernizr that includes every option available in the custom builder ( including extras such as HTML5Shiv, resource loader (modernizr.load), media queries test, and the addition of CSS class names to the html tag based on the test results from Modernizr.

The custom build of Modernizr enables HTML5 elements in IE (read more about it at But, now, with our audio player, we have the opportunity to use the other Modernizr function that is available as an extra, that is, modernizr.load.

Audio support in browsers is not as simple as we would expect it to be. Different browsers expect different formats because of licensing restrictions. Some browsers do not even support HTML5 audio. It would be perfect to use a framework that abstracts away all these for us. Looking at, we see that the recommended suggestion is to use a framework called mediaelement.js to help us deal with these issues. is a site that tells you which of these new features are available for use and how they should be used on browsers that do not support them.

Let us use this framework for our audio player only when audio support is not detected.

First, we download the framework from and copy all the files from the build folder into js/vendor/mediaelement/. Then, we shall add the cross-browser friendly audio markup for our player in index.html, as shown in the following code snippet:

<article class="t-audio"> <audio controls preload="none" autobuffer> <sourcesrc="festival.mp3" /> <sourcesrc="festival.ogg" /> </audio> </article>

Note that we need to specify the stylesheet in the head element to make sure it works perfectly on all browsers (instead of loading it just in time), as shown in the following code:

<link rel="stylesheet" href="js/vendor/mediaelement/ mediaelementplayer.css">

We then load the mediaelement.js only when audio support is missing by using Modernizr in our main.js file, as shown in the following code:

Modernizr.load({ test:, nope: { 'mediaelementjs': 'js/vendor/mediaelement/mediaelement-and-player.min. js' }, callback: { 'mediaelementjs': function() { $('audio').mediaelementplayer(); } } });

This code first tests if audio is supported with Modernizr. If it is not supported, then we load the necessary resources to make the audio work using our mediaelement.js framework. Once mediaelement.js is loaded, we call it, so that it runs and converts our audio files to a format that browsers which lack audio support will understand.

The previous screenshot shows our page rendering on a browser without support for HTML5 audio (falling back to Flash with mediaelement.js) and in a browser with support for HTML5 audio (using native controls provided by the browser).

When to use Modernizr.load?

Modernizr.load is a great utility when you have multiple files you want to load conditionally like in our audio player.

Sometimes, you want something to happen only when the user clicks on a link or an element. Instead of loading all the required assets beforehand and making the browser render the page slowly, you can load these assets just in time after the user has clicked on the element.

Using Modernizr to load CSS features

Modernizr also outputs the results of its tests for various HTML5/CSS3 features on the html tag of your page, as shown in the following screenshot:

This is very useful if you would like to style experiences based on the kind of features available. For example, we notice the class name called no-touch in the html element. This means the browser this page was loaded in, did not support touch interfaces. If touch was supported, then we could make all links with slightly more padding to account for large fingers trying to click on them. Let us add styles to our css/style.css file to do this, as follows:

.touch a { padding: 0.25em; background: #CEC3A1; border-radius: 0.5em; display: inline-block; }

Here is how our site looks on a browser that supports touch events (on the left-hand side) and one that does not (on the right-hand side):

Testing our site

Whew! That was a lot to get by! But wait, we are not done yet! We have written all the code, but how about some testing? There are so many variants of browsers out there and it is impossible to test on each and every one of them. Fortunately, it is pretty simple to test on most major versions of browsers.

If you are on Windows, irecommend you install the latest versions of Opera, Opera Next, Safari, Chrome, Chrome Canary, Firefox, Firefox Nightly, IE8, and IE10.

If you are on Mac, get every browser listed above, except IE. If you are able to afford it, buy a Windows Operating System and install it as a virtual image on Virtual Box ( Microsoft provides older IEs as virtual images for testing, which you could also install on Virtual Box using ievms (

For a far easier but less rigorous testing option—say when you have not yet finalized your website—try or

All of these browsers have developer tools that make it very easy to detect when a page is not rendered as expected.

Let us test our Sun and Sand Festival website in Internet Explorer 7. At first glance, everything appears to work as expected. But looking at the tabs, it seems like everything has gone haywire! The following screenshot displays our page on the Internet Explorer browser:

To debug this, let us use Firebug Lite to check what styles are being applied on these elements. You can install Firebug Lite as a bookmarklet on IE7 ( Clicking on that bookmarklet would enable us to use a constrained version of Firebug on IE7.

Using Firebug, we see a debugging window, as shown in the following screenshot:

Checking into our main.css, it seems like our media query-based styles are all being parsed and interpreted by IE7, irrespective of the conditionals within! For example:

.t-unit-1-2{ width: 100%; }

The previous style was declared within the media query @media only screen and (max-width: 750px), which is supposed to override the existing rule (.t-unit-1-2 { width: 50%; }) only if the query is satisfied. But IE7 simply ignores the features mentioned and blindly applies all the style rules it finds.

Thanks to conditional CSS class names, we can fix this trivially by adding an additional style rule to the original CSS declaration to prevent this override in IE6 to IE8.

HTML5 Boilerplate gives you three class names to use for such cases, described as follows:

  • .lt-ie7: Targets all IE versions that are lower than IE7 with this class name. This would apply styles to IE 6 and below.
  • .lt-ie8: Targets all IE versions that are lower than IE8 with this class name. This would apply styles to IE6 and IE7.
  • .lt-ie9: Targets all IE versions lower than IE9. This would apply styles to all IE versions 8 and below.

Thanks to this, we can now apply rules that target IE8 and below, which do not understand conditions in media queries by applying style rules as follows:

.lt-ie9 .t-unit-1-2 { width: 45%; }

As IE8 and below also do not support the box-sizing property (Mozilla Developer Network describes the effects of this property at, this means the widths of these boxes will expand as we add padding. Let us remove the margins on the parent element to prevent the boxes from stacking up, as shown in the following code snippet:

.lt-ie9 .t-before-1-6, .lt-ie9 .t-after-1-6 { margin-left: 0; margin-right: 0; }

However, that doesn't quite solve our problem. Then, looking further up, we notice that our grid cells, that is, the elements with the class t-grid__cell, have the display property set to inline-block. Knowing that IE7 does not apply this to any element other than those with natural inline property, we would have to add an additional declaration to make this work, as shown in the following code snippet:

.lt-ie9 .t-grid__cell { display: inline; }

Finally, now this works as we wanted it to!

Let us scroll to the bottom of the page. We notice the prices are all scrambled because of a lack of CSS3 transforms support in IE7, as shown in the following screenshot:

With Modernizr, all we need to do is to add this rule to our stylesheet:

.no-csstransforms .t-tickets__currency { position: static; }

This would make it more readable for any browser that does not support CSS transforms, as shown in the following screenshot:

Scrolling further down, we notice our SVG icons are missing as IE8 and below do not recognize SVG files, as shown in the following screenshot:

Again Modernizr comes to our rescue! In our main.js file, we will check the outcome of the SVG test in Modernizr and then replace all the SVG images with their equivalent PNG ones. Do note that this means you need a PNG equivalent for every SVG file you use in your HTML page. The code to replace SVG with PNG files is as follows:

if(Modernizr.svg == false) { $('img[src$=".svg"]').each(function() { this.src = /(.*)\.svg$/.exec(this.src)[1] + '.png'; }); }

Why use SVG?

We are using SVG icons as these can scale as per our needs of a responsive website, as SVG is a vector image format. Moreover, they are extremely lightweight compared to typical PNG files and can load significantly faster than PNG formats.

The following screenshot shows how IE7 renders the icons in PNG format thanks to Modernizr:

As you get into web development, you should spend more time using browser developer tools; Andi Smith wrote a good post outlining some of the features of each of them at

Testing on non-desktop browsers

Let us look at how the site looks on smaller-scale devices. The quickest and easiest way to do this would be to download Opera Mobile Emulator from and use one of the several available options to load our page. This emulator is shown in the following screenshot:

Choose one of the options on the left-hand side of the emulator and click on the Launch button to open an Opera browser instance that emulates how it would appear on the device you have selected.

For example, the following screenshot shows how our page renders on an instance of Opera Mobile Emulator for Amazon Kindle Fire:

The best part is that the Opera Mobile browser is one of the most modern mobile browsers available, which makes it a very good browser to test on when you are actively developing your website. It is also available on a wide variety of devices, which makes it easy to use Opera Mobile Emulator for testing various device widths if you are using media queries to style the page to adapt to different device dimensions.

If you also possess an iPhone running iOS 6, it is fairly easy to use Remote Debugging with Safari 6 and inspect the code using Safari developer tools (Max Firtman has more information on how to enable this at

If you have an Android device, you can enable debugging with Chrome for Android browser, but you need to install Android developer tools to do so. More help on how to do this is found in this guide to remote debugging on Chrome for Android at

If you have multiple mobile devices that run different browsers available at your fingertips, you can also use Adobe Edge Inspect from to test how these pages look in tandem across all of these devices.


In this article, we looked at adding some interaction to the site using jQuery plugins. We also looked at how to use Modernizr.load to load scripts to make it easy to conditionally detect support for HTML5 audio and load resources for browsers that lack support and render the audio correctly. We also looked at some of the ways we can debug our site using browser developer tools and verify how the page appears on various browsers.


Resources for Article :

Further resources on this subject:

You've been reading an excerpt of:

HTML5 Boilerplate Web Development

Explore Title