HTML 5 Mobile – Week 2 Summary
I am currently attending a live video class HTML 5 Mobile Web Development, and am summarizing the second lesson here in order to digest the material better and help some friends who got a late start. If you want to follow along, go to the class download page linked at the end and download the code.
This week starts our construction of “Tweetstr”, a mobile web twitter client. We create and edit the basic HTML and CSS files to display the home screen while exploring some new HTML 5 and CSS 3 tags as well as some settings specific to Apple devices such as the iPhone.
Section 1
We start with some basic html and css files.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="en"/>
<!-- TODO: Set Viewport -->
<title>Tweetstr</title>
<!-- TODO: Add CSS Reset -->
<link rel="stylesheet" href="style.css" type="text/css" media="screen" charset="utf-8">
<script type="text/javascript" charset="utf-8">
function navSelected(navItem) {
// First we need to clear all other nav items.
clearAllNavItems();
// Now give navItem the selected css class.
event.target.setAttribute('class', 'selected');
}
function clearAllNavItems() {
var navList = document.getElementById('navList');
for (var i = 0; i < navList.children.length; i++) {
var li = navList.children[i];
li.setAttribute('class', '');
}
}
</script>
</head>
<body>
<header>
Tweetstr
</header>
<nav>
<ul id='navList'>
<li id='liHome' onclick='navSelected()' class='selected' ></li>
<li id='liMentions' onclick='navSelected()'></li>
<li id='liFaves' onclick='navSelected()'></li>
<li id='liMessages' onclick='navSelected()'></li>
<li id='liSearch' onclick='navSelected()'></li>
</ul>
</nav>
<section id='home'>
<ul class='tweets'>
<li>
<div>
<img class='user-image' alt='JakeCarter'
src='user-image.png' />
<span class='username'>JakeCarter</span>
<span class='message'>I love twitter!</span>
</div>
</li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</section>
</body>
</html>
style.css
body {
font-family: "Helvetica";
}
/*
Header
*/
header {
width: 100%;
height: 44px;
text-align: center;
padding-top: 10px;
font-weight: bold;
font-size: 1.5em;
}
/*
Nav
*/
nav {
height: 44px;
width: 100%;
}
nav ul {
height: 100%;
width: 320px;
margin-left: auto;
margin-right: auto;
}
nav ul li {
display: inline-block;
float: left;
width: 64px;
height: 100%;
border: 1px solid #999999;
background-repeat: no-repeat;
background-position: center center;
}
/*
List
*/
section#home ul.tweets li {
min-height: 52px;
}
section#home ul.tweets li div {
padding: 2px;
}
section#home ul.tweets li div img {
float: left;
padding-right: 5px;
}
Notice how simple the doctype tag is for HTML 5:
<!-- HTML 4 --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <!-- HTML 5 --> <!DOCTYPE html>
Also, we’re using some new HTML 5 semantic tags, <header>, <nav>, and
<section> instead of generic <div> tags as with HTML 4.
<body>
<header>
Tweetstr
</header>
<nav>
<ul id='navList'>
<li id='liHome' onclick='navSelected()' class='selected' ></li>
<li id='liMentions' onclick='navSelected()'></li>
<li id='liFaves' onclick='navSelected()'></li>
<li id='liMessages' onclick='navSelected()'></li>
<li id='liSearch' onclick='navSelected()'></li>
</ul>
</nav>
<section id='home'>
By the end of section 1, the application looks like this:

The browser zooms way out, the nav items don’t fit on a single line, and we don’t have much styling yet.
Section 2
Let’s correct that zoom problem by setting the viewport.
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="en"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
<title>Tweetstr</title>
The viewport is a meta tag which Apple introduced for mobile Safari
which tells the browser what zoom level (or “scale”) should be shown for the
page and whether the user can zoom in or out when viewing that page. You can
set width to either a fixed number of pixels or device-width (recommended).
Viewport settings are also supported by Android and mobile Firefox.
We’ll also add a HTML 5 compatible reset stylesheet. This “resets” various styles to sane, known values for most of the tags supported by HTML 5. Jake has provided the one from HTML5 doctor.
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="en"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
<title>Tweetstr</title>
<link rel="stylesheet" href="html5reset.css" type="text/css" media="screen" charset="utf-8" />
<link rel="stylesheet" href="style.css" type="text/css" media="screen" charset="utf-8">
It needs to be added before the existing stylesheet as they are processed in order from top to bottom.
Here’s how the page looks by the end of section 2:

Now the zoom level is looking correct, and we have sane CSS values for our new HTML 5 tags, but we still have lots of clean up to go.
Section 3
Each of the five nav boxes has been set to a width of 64 pixels in the style.css file. 64 * 5 = 320, which is the width of the basic iPhone screen, so why do they not all fit on a single row like they’re supposed to? It’s because browsers by default uses the “content box” sizing model, where the given width and height are applied to the content with borders and padding added after. This makes our 64 pixel boxes take up more than 64 pixels.
CSS3 adds the ability to specify an alternate box sizing model “border box” where the width applies to the entire visible content, with the content area shrinking to accommodate the space required for borders and padding. See this for a more lengthy discussion on the topic.
Although CSS3 is not a final specification, we can use browser specific CSS styles to control the sizing model.
/* CSS3 official */ box-sizing: border-box; box-sizing: content-box; /* webkit (Chrome/Safari) */ -webkit-box-sizing: border-box; -webkit-box-sizing: content-box; /* Mozilla (Firefox) */ -moz-box-sizing: border-box; -moz-box-sizing: content-box; /* IE 8 */ -ms-box-sizing: border-box; -ms-box-sizing: content-box;
Let’s fix up our boxes by requesting the border box sizing model:
header {
width: 100%;
height: 44px;
-webkit-box-sizing: border-box;
text-align: center;
padding-top: 10px;
font-weight: bold;
font-size: 1.5em;
}
nav ul li {
display: inline-block;
float: left;
width: 64px;
height: 100%;
border: 1px solid #999999;
-webkit-box-sizing: border-box;
background-repeat: no-repeat;
background-position: center center;
}
Here’s what the page looks like at the end of section 3.

That looks better. All of the nav boxes fit on a single line.
Section 4
Before CSS3, using a gradients on the web meant creating image slices with the
required colors and using the CSS background-repeat declaration. Lots of
work and more importantly, lots of files for the browser to download. CSS3
allows us to create gradients through pure CSS without involving separate images.
Here Jake adds a gradient to the header.
header {
width: 100%;
height: 44px;
background-image: -webkit-gradient(
linear,
0% 0%,
0% 100%,
from(#666666),
to(#666666),
color-stop(.5,#333333)
);
-webkit-box-sizing: border-box;
text-align: center;
color: #ffffff;
padding-top: 10px;
font-weight: bold;
font-size: 1.5em;
}
And the nav:
nav {
height: 44px;
width: 100%;
background-image: -webkit-gradient(
linear,
0% 0%,
0% 100%,
from(#aaaaaa),
to(#aaaaaa),
color-stop(.5,#cccccc)
);
}
And a contrasting gradient for the selected state on each nav button:
#liHome.selected {
background-image: -webkit-gradient(
linear,
0% 0%,
0% 100%,
from(#dddddd),
to(#dddddd),
color-stop(.5,#cccccc)
);
}
#liMentions.selected {
background-image: -webkit-gradient(
linear,
0% 0%,
0% 100%,
from(#dddddd),
to(#dddddd),
color-stop(.5,#cccccc)
);
}
#liFaves.selected {
background-image: -webkit-gradient(
linear,
0% 0%,
0% 100%,
from(#dddddd),
to(#dddddd),
color-stop(.5,#cccccc)
);
}
#liMessages.selected {
background-image: -webkit-gradient(
linear,
0% 0%,
0% 100%,
from(#dddddd),
to(#dddddd),
color-stop(.5,#cccccc)
);
}
#liSearch.selected {
background-image: -webkit-gradient(
linear,
0% 0%,
0% 100%,
from(#dddddd),
to(#dddddd),
color-stop(.5,#cccccc)
);
}
Here’s what the page looks like after adding the gradients.

Section 5
Now let’s add the images which will form the face of our nav buttons. Notice how in the selected state, each box has two background images set, one for the gradient and one for the icon. The order is important here.
#liHome {
background-image: url('../../../shared/images/icons/icons/53-house.png');
}
#liHome.selected {
background-image: url('../../../shared/images/icons/icons/53-house.png'),
-webkit-gradient(
linear,
0% 0%,
0% 100%,
from(#dddddd),
to(#dddddd),
color-stop(.5,#cccccc)
);
}
#liMentions {
background-image: url('../../../shared/images/icons/icons/09-chat2.png');
}
#liMentions.selected {
background-image: url('../../../shared/images/icons/icons/09-chat2.png'),
-webkit-gradient(
linear,
0% 0%,
0% 100%,
from(#dddddd),
to(#dddddd),
color-stop(.5,#cccccc)
);
}
#liFaves {
background-image: url('../../../shared/images/icons/icons/28-star.png');
}
#liFaves.selected {
background-image: url('../../../shared/images/icons/icons/28-star.png'),
-webkit-gradient(
linear,
0% 0%,
0% 100%,
from(#dddddd),
to(#dddddd),
color-stop(.5,#cccccc)
);
}
#liMessages {
background-image: url('../../../shared/images/icons/icons/08-chat.png');
}
#liMessages.selected {
background-image: url('../../../shared/images/icons/icons/08-chat.png'),
-webkit-gradient(
linear,
0% 0%,
0% 100%,
from(#dddddd),
to(#dddddd),
color-stop(.5,#cccccc)
);
}
#liSearch {
background-image: url('../../../shared/images/icons/icons/06-magnifying-glass.png');
}
#liSearch.selected {
background-image: url('../../../shared/images/icons/icons/06-magnifying-glass.png'),
-webkit-gradient(
linear,
0% 0%,
0% 100%,
from(#dddddd),
to(#dddddd),
color-stop(.5,#cccccc)
);
}
Here are the nav buttons with their nice icons:

Section 7
Another nifty CSS3 feature is the new nth-child selector. Without this, if
you wanted to style every nth row of a list or table with a distinctive look,
you were forced to apply different classes to them, typically with javascript or
a server side language like PHP. CSS3 lets you select and style nth rows
directly from your stylesheet.
Here Jake gives every other (odd) row a gradient.
section#home ul.tweets li:nth-child(odd) {
background-image: -webkit-gradient(
linear,
0% 0%,
0% 100%,
from(#aaaaaa),
to(#aaaaaa),
color-stop(.5,#cccccc)
);
}
In addition to the shortcuts “odd” and “even”, you can put in a custom formula.
For example, if you wanted to style every 3rd row, starting from row 2, you
could use this: :nth-child(3n+2). Powerful stuff.
Here’s what it looks like in the browser:

Final Section
The page is starting to look like a proper mobile application. For the final section of this week, we’re going to add some Apple-specific fields to tell iOS devices some additional information about how the application should behave.
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="en"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<title>Tweetstr</title>
<link rel="apple-touch-icon" href="../../../shared/images/tweetstr-icon.png"/>
<link rel="stylesheet" href="html5reset.css" type="text/css" media="screen" charset="utf-8" />
<link rel="stylesheet" href="style.css" type="text/css" media="screen" charset="utf-8">
The first one, apple-mobile-web-app-capable determines whether the page can be
treated as a full screen application (without the Safari URL bar and navigation
buttons) when launched from the home screen. To get a web page to launch from
the home screen on iOS devices, open it in mobile Safari, click the “+” bookmark
button and choose “Add to Home Screen”. A web page saved this way with the meta
tag set will launch full screen. Without it, you get the normal mobile Safari
UI. The sugested name of the application short cut on the home screen comes
from the title of the web page.
The next Apple specific tag is apple-mobile-web-app-status-bar-style which
controls the appearance of the status bar for full screen web apps when launched
from the home screen. It can be set to “default”, “black” or
“black-translucent”. Here we use black.
The last meta tag we added sets the icon used on the device’s home screen for
the web app. Without this tag, iOS will save a miniature screenshot of the web
page as the application icon. This version of the tag allows iOS to add rounded
corners and that Apple glossy highlight to the icon. If you don’t want this (or
your icon already has these effect applied), use apple-touch-icon-precomposed
instead.
One additional Apple tag which Jake didn’t cover is apple-touch-startup-image
which allows you to specify an image to display as a splash screen while your
web application is loading. Because of the varying screen resolutions even
across Apple devices, this is not as useful as the other tags.
Here is the Add to Home screen for Tweetstr:

And here is the icon on the home screen:

And here it has been launched as a full screen web application. Notice there is no Safari UI and the title bar is now black.

That’s all until next week.
Useful Links
Class source code download: http://examples.oreilly.com/0636920014225
Class forum: http://forums.oreilly.com/category/104/HTML5-Mobile-Web-Development/
These came up in the chat channel during this week’s session
- mobile bookmark bubble - opensource code created by Google to remind users to add your web app to the home screen
- retina display - how to target the iPhone 4 retina display with a different CSS stylesheet
- Apple web app meta tags - Apple specific meta tags for mobile apps
- Open App Market – marketplace for mobile apps
Thank you, Thank you, Thank you. I also missed this class and was worried about catching up. This helps so much.