The Holy Grail of Mobile Layout

The Holy Grail of Mobile Layout

The perfect mobile layout should allow the presence of a navbar, a content area and maybe a footer toolbar. This layout should resize with orientation changes such that the bottom toolbar is always at the bottom and the content area resizes its width and height to fit the new dimensions. This is tough because, first off, there is not fixed positioning, and secondly, there is no single finger scrolling in Webkit for CSS defined scrolling regions.

it’s taken me a while to come up with a solution to these layout requirements. Any of you trying to make a Web app feel like a native mobile app know the frustration of trying to deal with orientation change and complex layout. Not being able to make a toxic mix of viewport meta tags, CSS media queries and onorientationchange events work to give me a fluidly resizing layout when the mobile device’s orientation changed drove me to despair. I compensated early on using JavaScript to resize everything, except I had to pay a performance penalty, especially if an app was complex. After a lot of sweat and blood and endless trial and error, I finally came up with a CSS only solution to making a layout that resizes smoothly with orientation changes.

So, the first big mistake, one that everyone and their brother recommends, is not to use the meta tag viewport settings of device width and device height. Instead, just use the initial scale, maximum scale and user scalability:

<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

The reason is that no matter what you set the width and height to with CSS, Webkit insists on thinking the document should have the height and width from when the document first loaded. This happens even if you use a CSS value of “width: 100%”. Switching from portrait to landscape, you’ll see that your layout fails to fill the width of the landscape screen:

iPhone Portrait Layout

iPhone Portrait Layout

iPhone Landscape Layout

iPhone Landscape Layout

As you can see with the landscape orientation the layout fails to fill the available width of the device. This app has its root elements’ widths set to 100% and a meta tag of:

<meta name="viewport" content="width=device-width; height=device-height; initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

Removing the device width and height from the meta tag will give us the fluid layout we seek:

<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

With the above change, when switching this document loaded in portrait orientation to landscape mode orientation we get a resized document the way we would like:

iPhone Landscape Layout Correctly Resized

iPhone Landscape Layout Correctly Resized

OK, so we have a navbar on the top, but what if we want a toolbar on the bottom? No problem. We can accomplish that with a few adjustments. To fix the toolbar to the bottom we’ll use absolute positioning. One thing to remember about this layout technique, if you are going to have navbars or toolbars, you’ll need to adjust the height of the content so that it fits the space left over by the bars. I do this using a class or class on the content section. A navbar or toolbar has a default height of 45 pixels, so you’d want to position your content that distance from a navbar or toolbar. To make this work, we’re going to have to use absolute positioning on the content section and on any bottom toolbar. One thing rather frustrating about using absolute positioning on block elements is that it causes them to collapse to what their content is, even with they have a width of 100%. We can get around this by setting the appropriate side to 0 pixels. For a bottom toolbar this could be something like this:

.toolbar.bottom {
    height: 45px;
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
}

With the above measurement, we have a toolbar that is 45px high fixed to the bottom and stretching from side to side. This toolbar will maintain these dimensions and placement even with an orientation change. We’ll need to do something similar for the content area. Like I said, we’ll need to use absolute positioning and account for any space taken up by a nav or toolbar. I use classes to do this, such as “withNavbar”, or “withNavbar withBottomToolbar”, or “withBottomToolbar”. The CSS for these classes would be something like this:

/* Definition for content area that fills the screen: */
#content {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}
#content.withNavbar {
    top: 45px;
    right: 0;
    bottom: 0;
    left: 0;
}
#content.withBottomToolbar {
    top: 0;
    right: 0;
    bottom: 45px;
    left: 0;
}
#content.withNavbar.withBottomToolbar {
    top: 45px;
    right: 0;
    bottom: 45px;
    left: 0;
}

We also need to make sure that the document’s content doesn’t bleed down below the bottom toolbar. We do this by wrapping the entire document in a div. I give it an id of #main:

<body>
	<div id="main">
		<div class="navbar">
			<h1>The Title</h1>
		</div>
		<div id="content" class="withNavbar withBottomToolbar">
			<ul class="table-view">
				<li><span class="title">Item One</span></li>
				<li><span class="title">Item Two</span></li>
				<li><span class="title">Item Three</span></li>
				<li><span class="title">Item Four</span></li>
				<li><span class="title">Item Five</span></li>
				<li><span class="title">Item Six</span></li>
				<li><span class="title">Item Seven</span></li>
				<li><span class="title">Item Eight</span></li>
			</ul>
		</div>
		<div class="toolbar placement-bottom">
			<div class="button">Edit</div>
			<div class="button">Save</div>
		</div>
	</div>
</body>

The styles for the div#main would be:

#main {
	width: 100%;
	display: -webkit-box;
	margin: 0 0 0 0;
	padding: 0;
	height: 100%;
	-webkit-box-orient: vertical;
	-webkit-box-align: stretch;
	-webkit-box-sizing: border-box;
	-webkit-transition: all 0.25s  ease-in-out;
	overflow: hidden;
	position: absolute;
	top: 0;
	left: 0;
	bottom: 0;
	right: 0;
}

Although the above arrangement solves the layout problems for mobile interfaces with automatic adjustment with orientation changes, it presents a new problem. That’s the problem of making the data in the content area reachable by the user. You’ll need to add a way for the user to scroll just that area. Normally the whole document would scroll with the browser, with the result that the top part would scroll out of view. Since we’ve fixed the toolbar to the bottom and have the height of the content area control by absolute position affecting its top, right, bottom and left, we need to provide a way to enable scrolling. Actually we could do this very simply using the CSS overflow property: #content { overflow-y: auto; }. However, on mobile Webkit this requires a two finger gesture. Most users would not expect this. They’ll use a single finger and think that the content is not scrollable.

There’s a simple way to provide single finger scrolling with a JavaScript module called “iScroll” created by Matteo Spinelli. This is a great implementation which provides deceleration animation of the scrolling, just like iOS, Android and other mobile OSes. One thing to be aware of when using iScroll, you don’t use it directly on the content container as this would cause that contain to slide up and down over the navbar and toolbar. Instead you’ll need to add an extra div tag inside it and use iScroll on that. iScroll will then enable scrolling of the div inside the content div. There are a number of options, my favorite is for desktop simulation. Here how you would do it:

<div id="content" class="withNavbar withBottomToolbar">
    <div id="scrollwrapper">
        <!-- Content In Here -->
    </div>
</div>
.........

<script type="text/javascript">
    var scroller = new iScroll(’scrollwrapper’, { desktopCompatibility : 
        true });
</script>

This gives you a basic mobile Web interface with a top navbar, a bottom toolbar and a content area with scroll that resizes quickly with orientation change.

Since publishing this article, I’ve created a framework for creating mobile Web apps. It uses many of the techniques explored in my blog posts. You can learn more about the framework by visiting ChocolateChip-UI.com. There are demos you can try in your desktop browser or on your mobile device.

Advertisements

Apple’s HTML5 Demo

OK, there’s been so much controversy about Apple’s HTML5 demo page (http://www.apple.com/html5/). Of course, you can go to the Mozilla developer site and find links to their own CSS3 examples like this: https://developer.mozilla.org/En/CSS/Using_CSS_transforms. It only works in Firefox. Hmmm… You can find similar pages on the Opera developer site. Hmmm… You can find similar ones from Google as well, oh and from Microsoft too. Do you see a pattern? Every browser vendor is putting up examples of how their browser renders whatever it is they’re trying to show off. So is it disingenuous for Apple to post their HTML5 demo? No.

All of this started with a blog post by a Mozilla evangelist, Christopher Blizzard: http://www.0xdeadbeef.com/weblog/2010/06/intellectual-honesty-and-html5/

Since Netscape Navigator 6, the Mozilla team for years lead the charge in establishing new standards for the Web. However, in June of 2005 Apple release the source code of the rendering engine for their Safari browser as and open source project known as Webkit. Even before the creation of the Webkit project, the Safari team had managed to create code to pass the Acid 2 test, the first browser to do so. Since then the Webkit team has introduced many new feats for the Web: the canvas tag, multiple backgrounds, background sizing, background clipping, rounded corners, text shadow, box shadow, text stroke, CSS gradients, CSS image masks, border images, CSS transforms, CSS transitions, CSS keyframe animation, as well as support for multi-touch events, etc. David Hyatt from the Webkit team has submitted all of these to the W3C for standardization. Many of these have already been adopted by the Mozilla team into Firefox. That’s why it’s interesting to see Mozilla’s Christopher Blizzard reacting Apple HTML5 demos as follows:

“The demos that they put up are just filled with stuff that Apple made up, aren’t part of HTML5 and are only now getting to the standards process. Part of CSS3? Kind of, sort of, but under heavy development and still in a feedback process.”

Then he goes on to say:

“The most important aspect of HTML5 isn’t the new stuff like video and canvas (which Safari and Firefox have both been shipping for years) it’s actually the honest-to-god promise of interoperability. Even stodgy old Microsoft, who has been doing their best to hold back the web for nearly a decade, understands this and you’ll see it throughout their marketing for IE9. (Their marketing phrase is “same markup” – watch for it and you’ll see it everywhere in their messaging.) The idea that the same markup, even with mistakes, will be rendered exactly the same. HTML5 represents the chance for browsers to work together and find common ground.”

OK, then why are there so many sites that use only CSS3 with -moz prefixes, including stuff on mozilla.com? If he wants one code to work everywhere always, then why have the Mozilla guys tried to persuade the W3C to use different syntax from the CSS3 features that the Webkit team introduced? We’re talking border radius, gradients, etc. If we wanted one code that worked everywhere we would still be using HTML 1.0. Progress is always painful, like a snake outgrowing its skin and shedding it. To me it seems like his biggest gripe is that most innovation on the Web today that is impacting standards seems to be coming from the Webkit team. This has meant that the Mozilla team is now in react mode trying to play catch up or minimalize the perception of Webkit’s advances over the last five years.

If i download the alpha of Firefox 3.7 right now, it’s got built-in support for the stuff that he’s complaining about in the above paragraph, stuff that is still in early recommendation status. Then there’s Mozilla’s decision to dump the HTML5 client-side database API for their own JavaScript based API for database calls. They apparently thinks developers don’t know how or don’t feel comfortable writing SQL. Hmmmm… What kind of developers are those? Sounds like sounds to me like a lot of their developers only know JavaScript so they want a JavaScript API. Check out the reaction of real developers in the comments section of the above link.

So, it seems like the Mozilla team is heading down a path to somewhere. It’s just that I don’t see myself wanting to head down that path. I want innovation that adds new capabilities and makes things simpler. But I don’t want simpler to mean I can do the hard things because simple can only do simple.

The CSS3 Wars

Remember the browser wars in the 90s? Then Netscape and Microsoft were engaged in a pitched battle for dominance of people accessing the Internet by enticing them with widely divergent implementations of HTML. In many cases you had to produce two completely different code bases to handle Netscape Navigator and Internet Explorer. To call it a developer’s nightmare would be mild. It seemed that the two companies could not agree on anything except to do things differently. Microsoft adopted the policy of bundling IE with their Windows operating system. It thus because the default browser an all Windows PC. They then cut a deal with Apple to make IE the default browser on the Mac. This effectively cut off Netscape from new users and directed the masses of people who were buying computers to access the Internet to use IE. Netscape basically curled up in a corner and died a slow death. In the early stages of its decline, Netscape had dedicated major resources to developing a new version of Netscape Navigator, one that would surpass IE. At the time the shipping version of Navigator was 4.8. Because the new version was to be so revolutionary, they changed its version to 6, skipping 5. By 1999 IE5 had become the dominant browser.

In 1998 Netscape opensourced their Mozilla project, as the new browser was called internally. In all, it took for four grueling years for Netscape to ship Navigator 6. It was bloated, but it was the first implementation of advanced CSS, DOM and JavaScript that would become the basis for the standards endorsed by the W3C. But Microsoft shortly thereafter shipped IE6. Enterprise workers rallied to IE6 and created Web sites that required it. Netscape continued to languish. In 2002 some enterprising developers took the opensource code for Navigator 6 and created a standalone browser that was lithe and fast. It would eventually be named Firefox. Shortly thereafter Apple came out with the own browser called Safari.

After the demise of Netscape, Microsoft disbanded their IE team and sat on their haunches. They mistakenly assumed no one would ever give up IE for another browser because the Web was being developed to be compatible with it. But the mere existence of Navigator 6 sparked intense interest among Web developers and designers, the prospect of tableless layout based on CSS. People began exploring the numerous bugs in IE6 and found ways to give one kind of CSS to it while using the cleaner, more elegant CSS for Mozilla browsers. It was finally possible to break out of the constraints of nested tables to create complex and sophisticated layouts.

At first, all the innovation in CSS was coming from the Mozilla/Firefox crowd. In time, though, Apple saw it in their strategic interest to have an opensource and powerful platform for Web applications. They opensourced their browser, calling it Webkit, and put resources in add advanced CSS features to it. Meanwhile Microsoft realized that a lot of people, actually, practically anyone who did Web develop, were criticizing IE6 for it’s innumerable bugs and bad implementation of CSS. There was a grass roots movement to dump IE, and it was gaining marketshare. Microsoft reconstituted the IE team and put them to work to fix some of the more egregious bug, but not all of them. Thus they shipped IE7, somewhat less buggy than IE6, but years behind Firefox and Webkit. By this time Apple had released its iPhone and iPod touch, which used Webkit as the rendering engine. And Google began building their own browser based on Apple’s Webkit.

Apple’s Webkit team had pushed the petal to the metal, pushing advanced CSS3 features into the browser at a dizzying pace. Whereas previously Firefox had been leading the charge in pushing advanced CSS, this crown had been snatched by the Webkit team. Seeing more and more users abandoning their browser because of its poor support for Web standards, Microsoft again decided to fix more bugs, releasing IE8 that could finally render CSS the way Opera, Firefox an Webkit had been able to do years previously. At this time the Webkit browser took over the Mobile space, dominating with the iPhone, iPod Touch, Palm Pre, Android and Nokia phones. Mobile Web development was Webkit development. Maybe this caused some envy in the Mozilla camp. Probably the release of Google Chrome, a browser based on Apple’s Webkit that rivaled Firefox for geek attention and respect, cause a change in mood in the Mozilla camp.

Seeing Firefox being left behind by Webkit’s push to implement advanced CSS3 features, they needed to play catch up. However, they sometimes chose to implement things differently from Webkit. They always had their reasons, but if Webkit had already implemented a feature and had submitted it to the W3C as a recommendation for standardization, why would the Firefox camp need to implement something different and they campaign to get their implementation accepted for standardization? This means that now we have write different CSS for border radii, CSS gradients. In general, the Webkit implementation is slightly more flexible than the Firefox version, though also more verbose. And now Microsoft has come back. As consumers and enterprise users continue to abandon IE, Microsoft is hard a work on IE9. They claim it will have full support for HTML5 and CSS3. If you go to their IE9 main page they have a graph of browsers’ performance with a suite of CSS3 test. Only IE9 passes these test 100%. All the other browsers fail miserably. Only one thing, this test suite was made by the IE team. That’s like students make up and administering their test to themselves. At the moment, as of beta 2, they only have support for borer radius, and that is implemented poorly with noticeable artifacts on the curves. From looking at what they have said they will support, it looks like once again Microsoft will release the most advanced version of IE that will at the same time be years behind other browsers. What scares me the most is that on their site the IE team discusses on videos that they looked at how everyone else was doing CSS3 and didn’t like their implementations. So they are going to do it their way. That means that whatever they implement will not look the same as other browsers, yay!!! We love cross-browser compatibility. So, between IE9, Firefox and Webkit, oh, and Opera, expect to be writing multiple versions of the CSS to accomplish the same thing in the different browsers. We are in the midst of the CSS3 Wars.

One thing to be aware of, in the mobile space there is but one browser and it’s Webkit. We’re talking about iPhones, iPod Touches, iPads, Android phone, Chrome OS, Palm Pre, and the new BlackBerry OS 6. That’s basically the entire smart phone, mobile device market there. This means that the Webkit code for everything will persist in developer usage and mindshare regardless of what Mozilla and Microsoft do. While desktops are not going away anytime soon, all growth and new momentum is in the mobile space. Webkit owns the mobile space. If you want to support Web anything in that space, you better be proficient in Webkit. Will the W3C force the Webkit team to adopt CSS3 standards pushed by Microsoft and Firefox? Maybe, but considering how Steve Jobs is pushing back against Flash, maybe not. My gut feeling is that in the future we’re going to have to deal with a fragmented implementation of CSS3 standards forcing us to write multiple instances of CSS3 to work across different browsers, the same as we’ve always done.

What is HTML5?

If you ask 20 different people what HTML5 is you’ll probably get 20 different answers. It’s bandied about so much to convey more than it is. Simply put, HTML5 is just HTML cleaned up, simplified, but with some tags that finally make semantic sense. Because of that, with just a few CSS tweaks, browsers can properly render HTML and XHTML documents with HTML5 tags. All modern browsers will render HTML5 tags properly when included in regular HTML/XHTML documents.

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width; height=device-height; initial-scale=1;">
      <title>My Kick Ass Web App</title>
   </head>
   <body>
      <article>
          <header>
             <h1>Article One</h1>
          </header>
          <aside><aside>
          <section></section>
          <section></section>
          <section></section>
          <footer></footer>
      </article>
      <article>
          <header>
             <h1>Article Two</h1>
          </header>
          <section></section>
          <section></section>
          <footer></footer>
      </article>
   </body>
</html>

All modern browsers can also render the canvas, audio and video tags of HTML5. When someone says that HTML5 is going to do [will in the blanks], you need to ask, “What do you mean by HTML5.” If the response is semantic markup, fine. If they mean audio and video tags, those are already here. Are they referring to Canvas and SVG, they have been around for a number of years. Are they referring to all the cool CSS3 stuff? That’s been around for a few years already. In general when you hear someone talking about how HTML5 is going to be such a big deal, or not, they probably referring to some mix of all of these. And that’s OK because HTML5 also supports all of these. But so does HTML/XHTML. Well, except for IE. It’s funny how we can send people into space, but here on earth there are people who still use IE.

The point is, we can use any of these in any combination right now. However, as with the uptake in XHTML and CSS based layout adoption at the start of the century (Wow! was it that long ago?), HTML5 combined with all these other features will be the future of Web develop. Actually, let me rephrase that, HTML5 will be the basis for a lot of connected application development. With HTML5 capable browser gaining the ability to render to GPU and enable offline modes such as local storage, the whole concept of a Web app verses a regular app will change to a point where the average user can’t tell the difference. Skilled designers and developers can already create Web apps that look and feel like native apps on iPhone, iPad, Adroid and Palm Pre. What the adoption of HTML5 will bring is the functionality of desktop type apps, leaving behind the limitations of the link/click Web site era.

Creating a Web App From a Single HTML5 Document

Works with Safari, Chrome, iPhone, iPad, Adroid

Because the focus of this blog is about CSS3 and HTML5, I will only be discussing their implementation on browsers that support these. If you’re using IE6, IE7 or IE8, you’re out of luck. These are very backwards as far as support for present day Web technologies are concerned. I’ll mostly be looking at the developments taking place on Safari/Chrome/Firefox/Opera. And if the IE team can ever ship IE9, we’ll include that as well.

With the widespread adoption of smart mobile devices the state of Web development has been transformed beyond recognition. First there was the Web 2.0 Ajax revolution. Instead of links leading off to another page, a click would result in only a part of the page being updated with new data retrieved from the server. The power of smart devices that are literally computers that fit in the hand has given rise to a new development module: Web apps. The Web part of the name can be misleading because, depending on its design and purpose, after the initial download, a Web app may not need any further connection to the Web. Also, a Web does not need to be for mobile devices. With special attention one could make an app that works for mobile and desktop/tablet.

To create a Web app can be quite complicated, or quite straightforward. I’m going to take the straightforward approach and show how with a minimum of code you can turn a single HTML page into a multipart Web app with cool CSS3-based animation during navigation. As a side benefit, no images shall be harmed in the creation of this app. All graphics will be created with CSS3. We’ll need to start with a basic document. For the purposes of this article I’m going to use HTML5. Actually, the markup and CSS3 code could be implemented in HTML 4 or XHTML. But since HTML5 is the new darling of techies and regular folks alike, I’m using it.

An HTML5 document starts with a doctype. We indicate what language the document uses and a meta tag to indicate the type of encoding used. For the purposes of this demo I’m also going to include a meta tag for viewport properties for mobile devices. This will affect the display of the app on iPhones, Adroids, and Palm Pres. Here’s the basic document structure:

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width; height=device-height; initial-scale=1;">
      <title>My Kick Ass Web App</title>
   </head>
   <body>
   </body>
</html>

The next thing we need to do is implement the structure that will allow us to create the experience of a multi-page layout while having only one document. We can easily do this by using HTML5 semantic markup. The article tag makes this possible. In fact, the browser treats each article tag as if it were its own document. Each one can have its own h1. Similarly, search engines will treat each article as separate from the others so that the content is classified per article, not per document. I’m also going to use section tags for some fencing in of content, some buttons to return to the home page. Oh, well, and I’ll set up the home or landing page with its menu for accessing the other parts. Here’s the markup:

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width; height=device-height; initial-scale=1;">
      <title>My Kick Ass Web App</title>
   </head>
   <body>
	<article id="Home" class="current">
		<section>
<h1>Home</h1>
<p>		   <nav></p>
<ul class="menuList">
<li rel="#Article1">News</li>
<li rel="#Article2">Things To Do</li>
<li rel="#Article3">Confidential</li>
<li rel="#Article4">What Next?</li>
</ul>
<p>		   </nav></p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>		</section>
	</article>
        <article id="Article1">
		<section></p>
<h1>Everything You Didn't Want to Know About</h1>
<p>		   <span class="button back">Back</span></p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>		</section>
	</article>
	<article id="Article2">
		<section></p>
<h1>Explain to Me Exactly Why You Came to This Page</h1>
<p>		   <span class="button back">Back</span></p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>		</section>
	</article>
	<article id="Article3">
		<section></p>
<h1>I Know What You Did and I'm Telling</h1>
<p>		   <span class="button back">Back</span></p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>		</section>
	</article>
	<article id="Article4">
		<section></p>
<h1>How Do I Get Out of Here?</h1>
<p>		   <span class="button back">Back</span></p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>		</section>
	</article>
   </body>
</html>

You’ll notice on the Home page section that I have a nav tag with a menu. Not that unusual except that the menu items are just plain old list items, not anchor tags with href attributes. Note that each list item has a rel attribute with the value that it corresponds to. With a little bit of JavaScript this will create my navigation system. Similarly, the back buttons are not inputs or anchor tags but just basic span tags with classes. Using CSS3 I’ll use those classes to make those spans look and act like buttons, and a bit of JavaScript will make them facilitate backward navigation.

If you opened the above markup in an HTML5 capable browser, you wouldn’t see much, pretty plain Jane stuff. We need some CSS to make it look like some. We’ll also need some CSS3 to make it look better than something. I’m going to use CSS3 to create repeating background patterns, as well as background gradients, box shadows, text shadows, border radii and transforms. The basic look we’re going for initially is something like following image. Later we’ll make each article zoom full screen and allow navigation between them.

Basic rendering of styled articles

We’ll start off by getting rid of default padding and margins on the html and body tags. Then we’ll give the body tag the basic underling styling for our app:

html, body {
    padding: 0px;
    margin: 0px;
}
body {
    background: #cbd2d8;
    background-image: -moz-linear-gradient(left, #c5ccd4, #c5ccd4 75%, transparent 75%, transparent);
    background-image: -moz-linear-gradient(90deg, #496178, #2E4960);
    background-image: -webkit-gradient(linear, left top, right top, from(#c5ccd4), color-stop(0.75, #c5ccd4), color-stop(0.75, transparent), to(transparent));
    -webkit-background-size: 7px 100%;
    -moz-background-size: 7px 100%;
    font: normal 16px/22px Helvetica, Arial, Sans-serif;
   -webkit-text-size-adjust: 100%;
}
section, nav {
    display: block;
    padding: 20px;
}
article {
    display: block;
}

Next let’s style the h1 tags so they look like a typical app title header. Using a fancy background gradient and some text shadow will do the trick:

h1 {
	padding: 10px 20px;
	margin: -20px -20px 20px -20px;
	background-image: -moz-linear-gradient(top, #b0bccd, #889bb3 50%, #8195af 50%, #6d84a2);
	background-image: -webkit-gradient(linear, left top, left bottom, from(#b0bccd), color-stop(0.5, #889bb3), color-stop(0.5, #8195af), to(#6d84a2));
	text-shadow: 1px 1px 1px rgba(250,250,250,0.5);
	font: bold 24px/26px "Lucida Grande";
	letter-spacing: -1px;
	border-top: 1px solid #cdd5df;
	border-bottom: 1px solid #2d3642;
	text-shadow: 2px 2px 1px rgba(0,0,0,0.4);
	color: #fff;
}

Rather than going bit by bit I’m giving you all the styling parts now, except for a couple of pieces that will add navigation transitions.

html, body {
	padding: 0px;
	margin: 0px;
}
body {
	background: #cbd2d8;
	background-image: -moz-linear-gradient(left, #c5ccd4, #c5ccd4 75%, transparent 75%, transparent);
	background-image: -moz-linear-gradient(90deg, #496178, #2E4960);
	background-image: -webkit-gradient(linear, left top, right top, from(#c5ccd4), color-stop(0.75, #c5ccd4), color-stop(0.75, transparent), to(transparent)); 
	-webkit-background-size: 7px 100%;
	-moz-background-size: 7px 100%;
	font: normal 16px/22px Helvetica, Arial, Sans-serif;
	-webkit-text-size-adjust: 100%;
}
section, nav {
	display: block;
	padding: 20px;
}
article {
	display: block;
}
.button {
	-webkit-box-shadow: 2px 2px 3px #999; 
	-moz-box-shadow: 2px 2px 3px #999; 
	border: solid 1px #000;
	display: inline-block;
	cursor: pointer;
	padding: 4px 15px;
	-webkit-transition: all 0.5s  ease-in-out;
	-moz-transition: all 0.5s  ease-in-out;
}
.button:hover {
	-webkit-box-shadow: 0px 0px 8px #000; 
	-moz-box-shadow: 0px 0px 8px #000; 
}
.back {
	-webkit-border-radius: 10px;
	-moz-border-radius: 10px;
	background-image: -moz-linear-gradient(top, lightblue, darkblue 50%, blue);
	background-image: -webkit-gradient(linear, left top, left bottom, from(lightblue), to(blue), color-stop(0.5, darkblue));
	color: #fff;
}
ul, li {
	list-style: none;
	margin: 0px;
	padding: 0px;
}
.menuList {
}
.menuList li {
	cursor: pointer;
	padding: 8px;
	border-left:  1px solid #AAA;
	border-right: 1px solid #AAA;
	border-bottom: 1px solid #AAA;
	background-color: #fff;
}
.menuList li:hover {
	background-color: lightblue;
}
.menuList li:first-of-type {
	border-top: 1px solid #AAA;
	-webkit-border-top-right-radius: 10px;
	-webkit-border-top-left-radius: 10px;
	-moz-border-radius-topright: 10px;
	-moz-border-radius-topleft: 10px;
}
.menuList li:last-of-type {
	-webkit-border-bottom-left-radius: 10px;
	-webkit-border-bottom-right-radius: 10px;
	-moz-border-radius-bottomleft: 10px;
	-moz-border-radius-bottomright: 10px;
}
#Home {
	background: #cbd2d8;
	background-image: -moz-linear-gradient(left, #c5ccd4, #c5ccd4 75%, transparent 75%, transparent);
	background-image: -webkit-gradient(linear, left top, right top, from(#c5ccd4), color-stop(0.75, #c5ccd4), color-stop(0.75, transparent), to(transparent)); 
	-webkit-background-size: 7px 100%;
	-moz-background-size: 7px 100%;
}
#Article1 {
	background-color: #f8ffac;
}
#Article2 {
	background-color: #beffca;
}
#Article3 {
	background-color: #dbfff4;
}
#Article4 {
	background-color: #c2bfd4;
	background-image: -moz-linear-gradient(top, #c3c6cc, #c3c6cc 50%, transparent 50%, transparent); 
	background-image: -webkit-gradient(linear, left top, left bottom, from(#c3c6cc), color-stop(0.5, #c3c6cc), color-stop(0.5, transparent), to(transparent)); 
	-webkit-background-size: 10px 10px;
	-moz-background-size: 10px 10px;
}
#Article3 p {
	border: solid 2px #666;
	-webkit-border-radius: 20px;
	-webkit-box-shadow: 2px 2px 6px #666;
	-moz-border-radius: 20px;
	-moz-box-shadow: 2px 2px 6px #666;
	background-color: #fff;
	padding: 10px;
}
#More p {
	border: solid 2px #666;
	-webkit-border-radius: 20px;
	-moz-border-radius: 20px;
	background-color: rgba(120,120,120, 0.75);
	padding: 10px;
	-webkit-box-shadow: 2px 2px 6px #666;
	-moz-box-shadow: 2px 2px 6px #666;
	color: #fff;
	text-shadow: 1px 1px 1px #000;
}
h1 {
	padding: 10px 20px;
	margin: -20px -20px 20px -20px;
	background-image: -moz-linear-gradient(top, #b0bccd, #889bb3 50%, #8195af 50%, #6d84a2); 
	background-image: -webkit-gradient(linear, left top, left bottom, from(#b0bccd), color-stop(0.5, #889bb3), color-stop(0.5, #8195af), to(#6d84a2)); 
	text-shadow: 1px 1px 1px rgba(250,250,250,0.5);
	font: bold 24px/26px "Lucida Grande";
	letter-spacing: -1px;
	border-top: 1px solid #cdd5df;
	border-bottom: 1px solid #2d3642;
	text-shadow: 2px 2px 1px rgba(0,0,0,0.4);
	color: #fff;
}

These styles give us everything to create the image above. But now we need to add a bit more to create some transitions for navigation. Before we can navigate from one article to another, we’ll need to style the articles so that they can behave like separate parts. We’ll use absolute positioning and give each article a height and width of 100%. This would by default cause all the articles to stack on top of each other. Therefore what we’re going to do is move them offscreen. We’ll create a special class called “current” for the article we want to display, otherwise they’ll be offscreen. OK, so to do this we’ll need a little bit of JavaScript. This is just for one purpose, to change which article has a class of “current”. Then we’ll use CSS3 transitions to move the not current article off the screen and the current article onto the screen. I’ve already introduced a CSS3 transition for the .button class and .button:hover. But instead of targeting the box shadow, we’re going to target the left position of the article.

So, as I had mentioned earlier, we’re going to put the articles offscreen by using absolute positioning and negative left. Then we’ll transition them onto the screen when we add the “current” class to the article by giving it a left value of 0. The animation is all accomplished very efficiently by the CSS3 transition rendering without any of the problems of trying to do this with JavaScript. So, we need to update the CSS for the article tag and add a new class for “current”:

article {
	display: block;
	wwidth: 100%;
	wheight: 100%;
	wposition: absolute;
	left: -10000px;
	-webkit-transition: all 0.5s  ease-in-out;
	-moz-transition: all 0.5s  ease-in-out;
}
.current {
	left: 0px;
}

Now all we need is the JavaScript to add and remove the “current” class from the articles. Although I’m using jQuery for this, you could just as easily write the necessary JavaScript to do this. Here’s the code:

var sectionStack = ["#Home", "#Article1", "#Article2", "#Article3", "#Article4"];
$(document).ready(function() {
	$(".menuList li").click(function() {
		$.each(sectionStack,
			function(index, value) {
				$(value).removeClass("current");
			}
		);
		$($(this).attr("rel")).addClass("current");
	});
	$(".back").click(function() {
		$(this).parents().removeClass("current");
		$("#Home").addClass("current");
	});
});

This code only does two things. When the user clicks on a menu list item, the code grabs that list items rel attribute, which indicates which article to show. Then it removes the “current” class from all articles and sets that class to the target article. When the browser sees that class has been added, it renders the CSS3 transition, sliding the article that was current (Home) off the screen and sliding in the target article. Similarly, when the user clicks on the back button, the code removes the “current” class from the article and puts it on the home article, causing a CSS3 transition to take place. If you wanted to have deeper, nested navigation, you would have to use an array to keep tract of where you came from and were you’re heading. Just use the JavaScript array’s built in push and pop methods. I’ll probably show this in a later post.

This was not that much JavaScript or CSS, yet the result was a slick Web app. At the moment this demo works with Firefox 3.6, Safari 3, Google Chrome, iPhone, iPad, Android and Palm Pre. Firefox 3.6 does not have CSS3 transitions, although it does have transforms. I could have refactored the JavaScript to animate the transforms for Firefox 3.6, but I didn’t want to fork the code. Firefox 3.7, presently a downloadable alpha build, does support CSS3 transitions and this works fine with it. I could have implemented support for Opera, but since it still doesn’t have support for gradients, it looks awfully flat. I didn’t want to use images just for Opera, so I left it out for now. Everything else in Opera works fine: text-shadow, box-shadow, border radius and CSS3 transitions.

You can try the app out online or download the complete file.