Monday, February 13, 2012

Building a mobile web page in HTML5

This post is a part of a series of posts which originate from the course I am building on Wikiversity. The course does a deep dive on how to build three-tier applications for mobile devices using the MVC pattern for user interface development. The course can be found at; http://en.wikiversity.org/wiki/MWA. Even though the course will focus on using HTML5 and CSS3 for rendering the user interface, the course is more about building three-tier application software.

Lesson 2: Viewing pages without mobile devices
During this module we will create an approach to viewing a mobile web page (with desired CSS formatting) without using an actual mobile device. This is important because there are three main targets for the web pages; phones, tablets and desktops. There is considerable effort in creating the HTML, CSS and JavaScript for the different devices and to have a simple way to "toggle" between the different looks from within a desktop browser will ease software development. Once a web page is in its different formats (phone, tablet, desktop), has been successfully tested within the desktop browser it can then be tested on the target devices, this should be an iterative process.

Click here to review Lesson 1:Detecting the screen size

The Challenge
The challenge of this lesson is to create a simple way to "toggle" between the different style sheets to be applied for the different mobile devices. This "toggling" needs to be implemented in a way that does not impact the HTML and CSS. The files used to implement the final web site need to be left untouched so the testing approach can be easily executed across all the sites website without having to alter the files in preparation for the final release.

Swapping the style sheets (CSS)
Using the URL with some parameters is a very effective way to pass information into a web page as it is loading. The parameters put onto the URL are known as the Query String. To swap the Cascading Style Sheet (CSS) I have added a simple JavaScript to the head of the web page that looks at the parameters and swaps the CSS. The web page will also load normally without having a parameter appended to the URL. All this will be described in greater detail as we explore the actual html, css and javascript. ''For simplicity the main differences between the three pages is the number of columns being displayed.''

page loading with desktop style sheet
 
http://www.bit.bc.ca/dev/device.html?device=desktop&width=1200


page loading with tablet style sheet
 
http://www.bit.bc.ca/dev/device.html?device=tablet&width=800


page loading with phone style sheet
 
http://www.bit.bc.ca/dev/device.html?device=phone&width=320


Thoughts on screen size
Given these three previous screen shots it becomes apparent that with mobile devices in the mix we are dealing with a screen sizes between 320 pixels (smartphones) and over 1600 pixels (desktops). And to have consistency of screen sizes across the different devices is difficult to achieve for people set their screen sizes based on their needs, this is particularly true in the tablet arena where people may set their device to be anywhere between 600 and 1400 pixels wide (and this is will increase). At the edges of screen / device size it becomes easier to make decisions about user interface design. A small screen mobile device where the interface is less than 400 pixels managing the content on the screen is more set, this is the same with larger screen sizes as the space is relatively vast. It is the medium sized screens on the different devices where the challenge presents itself. A tablet where the manufacturer designed the device for a 800 pixel wide display and the user sets it to 960 for they have really good eyesight. How should the content be displayed? In the above example if the screen was less than 400 pixels the content was displayed in a single column, if the screen was less than 800 pixels the content was displayed in two columns, and above 800 pixels three columns were displayed. So deciding on content layout is more dependent on the set screen size than the device.

The HTML5, CSS and JavaScript

The HTML5 and JavaScript within the web page is very bare bones and only the tags necessary are included. The CSS is contained in three different files each utilized depending on which screen size is accessing the web page. Some new HTML5 features have been utilized to introduce these features and to better organize the web page. These will be explained later.

What's changed from the previous lesson
<meta name="viewport" content="width=device-width user-scalable=no initial-scale=1.0">

Additional parameters have been utilized with the viewport meta tag. These are to set the mobile device to remain a consistent size. Devices that allow zooming can be problematic on the smaller to mid-size devices.

What's new within this lesson
  1. The new HTML5 tags of <header> and <section> were added to the HTML page. This organizes the content and simplifies managing the CSS assigned to different areas of the screen. 
  2. A block of JavaScript to gather parameters from the QueryString and change the assigned style sheet and screen size. 
  3. Styles for the different screen sizes, with a focus on creating columns in the web page. 
pseudocode
  1. Rendered the web page in a similar way as previous versions of HTML.
  2. Add attributes to the '''name="viewport"''' meta tag to set the device size and not allow scaling (or zooming).
  3. Add the '''media=''' media queries to provide the ability to load different CCS depending on the screen size (mobile device).
  4. Load the querystring parameters into a key value array
  5. Change the assigned style sheet based on the device key value, otherwise use the style sheet assigned by media query
  6. Change the screens display width based on the width key value, otherwise use default values
  7. Display the screen height, width and useragent
  8. Render the web page with the correct style sheet and content width as provided in the key value array
  9. Within the style sheets set the desired margins, column count and formatting for the header and section tags.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Device Attributes</title>

<!-- meta tags -->
<meta name="keywords" content="">
<meta name="description" content="">
<meta name="viewport" content="width=device-width user-scalable=no initial-scale=1.0">

<!-- stylesheets -->
<link rel="stylesheet" href="/css/desktop.css" type="text/css">
<link rel="stylesheet" href="/css/tablet.css" type="text/css" media="only screen and (min-width:400px) and (max-width:800px)">
<link rel="stylesheet" href="/css/phone.css" type="text/css" media="only screen and (min-width:0px) and (max-width:399px)">

<script type="text/javascript" >
        // gather the http parameters from the URL and put them into an array for temporary storage
        var args = new Object();
        var query = location.search.substring(1);
        var pairs = query.split("&");
        for(var i = 0; i < pairs.length; i++) {
                var pos = pairs[i].indexOf("=");
                if (pos == -1) continue;
                var argname = pairs[i].substring(0,pos);
                var value = pairs[i].substring(pos+1);
                args[argname] = unescape(value)
        }
        // check the array to determine the device type and screen width requested change the style sheet and width displayed to web page
        // if no width is specified for device type use appropriate defaults
        // if no parameters were specified use the defaults as set in the <meta> and <link> tags
        if(args.device == "tablet") {
                document.write('<link rel="stylesheet" href="/css/tablet.css" type="text/css">');
                if(args.width)
                        document.write('<style>body {width: ' + args.width + 'px;}</style>');
                else
                        document.write('<style>body {width: 768px;}</style>');
                }
        else if(args.device == "phone") {
                document.write('<link rel="stylesheet" href="/css/phone.css" type="text/css">');
                if(args.width)
                        document.write('<style>body {width: ' + args.width + 'px;}</style>');
                else
                        document.write('<style>body {width: 320px;}</style>');
                }
        else if(args.device == "desktop") {
                document.write('<link rel="stylesheet" href="/css/desktop.css" type="text/css">');
                if(args.width)
                        document.write('<style>body {width: ' + args.width + 'px;}</style>');
                }
</script>
</head>
<body>

<header>
<script type="text/javascript">
// determine the screen height and width and display to web page
document.write("<h1>" + screen.availHeight + " x " + screen.availWidth + "</h1>");
// determine the user agent and display to web page
document.write( navigator.userAgent.toLowerCase() + "<hr>");
</script>
</header>
<section>
The purchase and use of mobile devices has exceeded laptops and desktops combined. The time has come where a mobile first strategy for content deployment should be your organizations default. And the desktop will be relegated to administrative and after-the-fact tasks. The Bowen Institute of Technology focuses its services, research and instructional development tasks in getting your organization to mobile. Not only from a technology perspective, but also from a process improvement and employee and customer education perspective. At the Bowen Institute of Technology we view knowledge management and business intelligence not as bits, bytes, data and stored information. We see it as the knowledge and intelligence stored in peoples heads and within their collaborations. Technology is a great tool for capturing and exchanging peoples knowledge and intelligence while also facilitating the interactions of communities of practice. If you desire a greater understanding of how we can help your organization excel in the world of mobile knowledge and distributed intelligence do not hesitate to contact us; <a href="mailto:info@bit.bc.ca">info@bit.bc.ca</a>
</section>
</body>
</html> 

tablet.css
The big changes for this style sheet are the margins being set to 10px and the column count being set to 2.
* {     font-family: arial, helvetica, sans-serif; }

body {
        width: auto;
        margin-right: 10px;
        margin-left: 10px;
}
header {
        font-size: 100%;
        font-style: italic;
        color: #000;
}
header > h1 {
        font-size: 150%;
        font-weight: bold;
        font-style: normal;
        color: #000;
        text-shadow: 1px 1px 3px #333;
}
section {
        -moz-column-count: 2;
        -webkit-column-count: 2;
        column-count: 2;

        -moz-column-gap: 1em;
        -webkit-column-gap: 1em;        
        column-gap: 1em;
        
        text-align: justify;
        font-size: 100%;
}
phone.css
The big changes for this style sheet are the margins being set to 5px and the column count being set to 1.
* {     font-family: arial, helvetica, sans-serif; }
body {
        width: auto;
        margin-right: 5px;
        margin-left: 5px;
}
header {
        font-size: 80%;
        font-style: italic;
        color: #000;
}
header > h1 {
        font-size: 150%;
        font-weight: bold;
        font-style: normal;
        color: #000;
        text-shadow: 1px 1px 3px #333;
}
section {
        -moz-column-count: 1;
        -webkit-column-count: 1;
        column-count: 1;

        -moz-column-gap: 0em;
        -webkit-column-gap: 0em;        
        column-gap: 0em;
        
        text-align: justify;
        font-size: 100%;
}
desktop.css
The big changes for this style sheet are the margins being set to 160px and the column count being set to 3.
* {     font-family: arial, helvetica, sans-serif; }
body {
        width: auto;
        margin-right: 160px;
        margin-left: 160px;
}
header > h1 {
        font-size: 150%;
        font-weight: bold;
        color: #000;
        text-shadow: 2px 2px 5px #333;
}
section {
        -moz-column-count: 3;
        -webkit-column-count: 3;
        column-count: 3;

        -moz-column-gap: 2em;
        -webkit-column-gap: 2em;        
        column-gap: 2em;
        
        text-align: justify;
}

Lesson Summary 
In this lesson we have explored how to add and consume parameters appended to the web site URL. These parameters were parsed by JavaScript and programming logic was developed to assign the correct style sheet and screen width depending on the values found in the parameters. The use of the meta tag "name=viewport" was also further expanded to include attributes to turn off scaling and to prevent zooming. The two new HTML5 tags of <header> and <section> were also added for better formatting of the html and to make specific style sheet changes to different areas of the page.

Business Value
The business value is it quickens the design process and that will save the designers time. It will assist in discussing design and allow demonstration of the site without having all the actual devices present. Mostly, it will ease the design and testing processes.