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.

Follow

Get every new post delivered to your Inbox.

Join 45 other followers