Newer posts are loading.
You are at the newest post.
Click here to check if anything new just came in.

May 05 2011

09:06

Choosing the Right Tools for Your Mobile Project

Advertisement in Choosing the Right Tools for Your Mobile Project
 in Choosing the Right Tools for Your Mobile Project  in Choosing the Right Tools for Your Mobile Project  in Choosing the Right Tools for Your Mobile Project

Mobile web browsing is the next big thing. At least that’s what the pundits say. Recent data shows there are about 4 billion mobile users (almost half the planet) (source). In 2011, smartphone sales will surpass desktop/laptop computer sales, moving over 400 million units per year (source).

But haven’t we heard this all before? Hasn’t the mobile web been the “next big thing” for each of the last several years? What gives? It doesn’t really matter that 4 billion people have mobile phones unless they are using them to browse the web.

In previous years, two big factors have prevented the mobile web from taking off like everyone thought: inferior hardware and sub-par web browsers. The iPhone changed both for the better in 2007. Smartphones have taken a giant leap forward in the last three years and mobile Safari has led to several WebKit-based mobile browsers being developed.

So thanks to the iPhone and several other mobile innovations that proceeded it, mobile is for real this time. 25% of those 4 billion people are using the web from their phone today. (source).

If you haven’t built a mobile website before, the whole scene might seem a bit overwhelming. Today we’re going to give you the information necessary to answer some of the tough questions that come up when designing a mobile experience:

  • Do we need a dedicated mobile site or just a mobile-optimized one?
  • What browsers do we optimize for? How can we test them?
  • Should we use a mobile framework? If so, are we depending on it for the UI?
  • Which mobile framework is the best fit for my project?
  • Which frameworks work best for building a native app?

The Browser Landscape

Prior to diving into your text editor and starting your first mobile site, it’s important to understand the lay of the land. Here are the worldwide browser leaders measured between July and December, 2010 according to StatCounter:

Browser-ww in Choosing the Right Tools for Your Mobile Project

One clarification to be made is that iPhone and iPod Touch are treated separately above, but they are both the same browser from a web developer’s point of view. So if their market share is combined appropriately, it comes in ahead of Opera by 3.34%, making it the market leader.

Opera is a big deal now because it’s platform-independent, available on most smartphone operating systems including iOS, Blackberry, Android, Windows Mobile and Symbian. Opera Mobile v10+ and Opera Mini v5+ (different browsers) both have solid web standards support. Opera also provides excellent developer tools for testing.

Most modern mobile browsers are built on the open source WebKit framework, which debuted in a mobile capacity on the iPhone. iOS, Android, Symbian (Nokia), webOS (Palm) and Blackberry v6+ devices all have WebKit browsers by default. WebKit’s javascript and web standards support is excellent, so the only real thing to worry about is optimizing for various device resolutions.

A few other browsers are not big players at the moment, but are worth keeping an eye on. SkyFire tops the list, available on Android and iOS devices. It recently made headlines for generating over $1 million after only three days on the app store, forcing Apple to temporarily disable sales for a short time because of the demand. SkyFire is known for it’s social media integration and ability to convert flash video to a native format that can be seen on the iPhone.

Firefox Mobile is another up-and-comer. It’s available for Nokia N900 phones or any Android 2+ phones and is based on the same technology as Firefox 4 for the desktop. It boasts great video support (including flash), social sharing features and even user agent switching for more advanced users.

Even Microsoft’s Windows Phone 7 is holding it’s own alongside iOS and Android browsers. So even a browser with the infamous “Internet Explorer” name gets a fresh start in the mobile space.

Mobile First

Luke Wroblewski was the first to boldly proclaim that we should design websites for the Mobile First. Luke argues that designing for mobile first helps you focus on the most important elements since you have such limited screen space. He also says that mobile phones are now capable of more than desktop browsers, such as location-aware features and multi-touch gestures. So why not have the full arsenal of capabilities available to you when designing?

Perhaps the most compelling reason to consider designing for mobile first revolves around media queries. Media queries are part of the CSS3 specification that allow you to specify certain styles based on device parameters, most notably width or height. With either of the following lines of code, I can show styles for a device no wider than 480px:

<link rel="stylesheet" type="text/css"
media="screen and (max-device-width: 480px)" href="styles.css" />

@media screen and (max-device-width: 480px) {
  .column {
    float: none;
  }
}

For a great run-down about media queries, check out “Responsive Web Design”, an article by Ethan Marcotte.

The problem with media queries is that they don’t resolve properly on many mobile devices (source: Rethinking the Mobile Web). They are, however supported well on modern desktop browsers and even enabled in not-so-modern browsers with help from a javascript file. So if we start with mobile and use media queries to progressively enhance the layout for the desktop, everything works out! By using media queries to optimize a desktop site for mobile, you run the risk of the mobile browser not rendering it properly.

Meta Tags

Mobile meta tags aren’t nearly as important as they used to be, but there are still three mobile-specific tags worth understanding:

<meta name="viewport" content="width=240, height=320, user-scalable=yes,
initial-scale=2.5, maximum-scale=5.0, minimum-scale=1.0" />

The viewport meta tag is the newest and most powerful when it comes to mobile, allowing developers to share the width/height of their content with the browser and control how the content is allowed to be zoomed/scaled by the user. Most modern mobile browsers support this tag. Apple gives a nice overview of what the viewport tag is capable of and also details a few iOS-specific tags in their HTML reference library.

<meta name="HandheldFriendly" content="true" />
<meta name="MobileOptimized" content="width" />

When the viewport tag is not supported by the phone, it can fall back on one of two older meta tags. Both should become more obsolete in the coming years, but are a good fallback presently. “HandheldFriendly” simply identifies your site as “mobile friendly” to the phone, but doesn’t let you set any additional parameters. “MobileOptimized” is a proprietary Microsoft tag, which does allow you to specify a width, but isn’t flexible as to zooming or scaling. (source: http://davidbcalhoun.com/tag/mobileoptimized)

Use a Mobile Framework

While it’s not required, most great mobile experiences start with a framework. They help developers create rich, interactive mobile sites with minimal code and are optimized for several platforms out of the box. Popular frameworks also have growing communities, dedicated to improving the product across different browsers as the technology rapidly evolves.

jQTouch

Jqtouch in Choosing the Right Tools for Your Mobile Project

This framework is primarily focused on optimizing websites for the iOS operating system, although it can be easily adjusted to work well for other WebKit-based browsers as well. It’s very flexible and has a solid community of developers working to improve it. (http://jqtouch.com/)

Pros

  • Very popular framework with an active community
  • Optimized for WebKit, especially iOS
  • Great native-like animations and themes
  • Good for javascript novices

Cons

  • Nearly 70k minified, includes desktop version of jQuery
  • It takes some research to find good tutorials
  • Meant for smaller sites, probably not web applications

jQuery Mobile

Jquery in Choosing the Right Tools for Your Mobile Project

jQuery is the big player we all know and love on the desktop. They have recently released an Alpha of their mobile framework, which brings a lot of the same goodness to mobile devices. What’s most impressive about this framework is it’s adaptability across all the most popular browsers and operating systems. Their graded browser support chart clearly outlines the support across all platforms. (http://jquerymobile.com)

Pros

  • Built on the world’s most popular javascript framework
  • Huge community
  • Supports virtually every modern mobile browser
  • Only 13k minified
  • Great UI tools, better for cross-device consistency
  • Great documentation, novices can pick it up easily

Cons

  • Only in Alpha 2 phase, still has a little ways to go
  • Doesn’t really look “native” on any device because it supports so many browsers

Zepto

Zepto in Choosing the Right Tools for Your Mobile Project

Zepto, created by Thomas Fuchs (script.aculo.us author), is the perfect mobile framework for jQuery pros. It’s less than 3 kb minified, enables jQuery-compatible syntax (most of it) and is optimized for mobile WebKit browsers. There are no default UI controls, so it’s definitely for the more minimalist coders that are interested in a custom design. The fun chalk iPad project from 37signals was created with Zepto. (http://zeptojs.com/)

Pros

  • Only 3.3k minified!
  • Active community led by someone with serious javascript chops
  • Designed with jQuery-compatible syntax

Cons

  • No UI tools, only the basics
  • Documentation is good, but demos are lacking
  • Geared towards more experienced jQuery developers

Sencha Touch

Sencha in Choosing the Right Tools for Your Mobile Project

Sencha (includes EXT JS desktop framework) touch is a very impressive javascript framework specifically geared for mobile web apps. It’s probably the best all-in-one framework right now. However, it’s not for beginners. All of the front-end syntax is javascript, so you need javascript chops and experience with the library to make the most of it. Right now it is compatible with iOS and Android devices. (http://www.sencha.com/products/touch/)

Pros

  • It’s beautiful
  • Great documentation and (paid) support
  • Scalable, built for serious web apps
  • Has all the UI tools you would need

Cons

  • Only optimized for iPhone and Android so far
  • Steep learning curve, must be experienced with EXT JS
  • All javascript front-end syntax
  • Runs fast, but framework is 369k

Yahoo! Blueprint

Yahoo in Choosing the Right Tools for Your Mobile Project

Blueprint is a robust framework meant to optimize for literally thousands of different devices. It takes raw XML, communicates with Yahoo!’s web services to generate the pages, then renders the content optimized for the device. The SDK is for more advanced users, but for anyone that has experienced the mobile Yahoo! properties, you know it is very powerful. (http://mobile.yahoo.com/devcenter)

Pros

  • Comprehensive device support
  • Robust features and APIs

Cons

  • As mobile browsers evolve, this might be overkill
  • Requires Yahoo! web services to work
  • Steep learning curve
  • Developer site and documentation is confusing

SproutCore Touch

Sproutcore in Choosing the Right Tools for Your Mobile Project

SproutCore is a popular javascript framework for desktop browsers that gives web apps a native look and feel. It’s best known for running Apple’s MobileMe and iWork web services. SproutCore Touch basically adds touch support to the existing framework. It’s still one codebase as I understand it. So if you already have a SproutCore app, it’s pretty easy to optimize it for something like the iPad. (http://blog.sproutcore.com/post/531215199/introducing-sproutcore-touch)

Pros

  • Gives almost instant touch support to existing SproutCore apps
  • Mature codebase with some big supporters, like Apple
  • UI tools are beautiful on the desktop and mobile devices

Cons

  • All javascript front-end syntax
  • Steep learning curve

Jo

Jo in Choosing the Right Tools for Your Mobile Project

This newer framework is lightweight (8k) and has some really nice elements to it. Compatible with webOS, iOS, Android and Symbian, it’s probably a great fit for smaller sites that don’t have a lot of UI demands. Jo is still new, but it will be really interesting to see how the open source community builds on this solid foundation. (http://joapp.com/)

Pros

  • Lightweight (8k), still has nice UI tools out of the box
  • Compatible with several operating systems

Cons

  • Community is not as active as with other frameworks
  • UI doesn’t really feel native on any device
  • Codebase still needs more work to be considered with the top-tier frameworks

DHTMLX Touch

Dhtmlx in Choosing the Right Tools for Your Mobile Project

This framework is much like Sencha and SproutCore in that it’s all javascript syntax on the front-end and the code is derived from a desktop framework. With that comes an arsenal of robust UI elements and functionality. The touch framework just came out in December of 2010, but look for it to be a player moving forward. (http://dhtmlx.com/touch/)

Pros

  • Comprehensive UI tools to fit any need
  • Built to do heavy lifting for web applications
  • Cool drag & drop visual designer tool (see video)
  • Rich feature set based on desktop framework, lots of potential as the framework grows

Cons

  • All javascript front-end syntax
  • Steep learning curve
  • Still in Alpha at the time of writing, documentation is evolving

CSS Grid Framework

The CSS Grid framework is completely different from the above-mentioned tools because it doesn’t include any javascript or UI tools. Technically, it’s not a mobile framework. It’s a fluid, 12-column grid that scales from 1140px wide down to 430px beautifully. You can build with a Mobile First mentality and use media queries to scale your site all the way up to 1140px.

The days of fixed-width websites are numbered as mobile becomes more of a focus for designers and their clients. The CSS Grid framework gives designers the ability to design for one flexible grid and optimize for devices across the entire spectrum.

Pros

  • Same HTML/CSS works for your desktop and mobile site
  • Progressive enhancement at it’s best thanks to media queries
  • No javascript dependencies to render on mobile devices

Cons

  • Not all designs can work with this framework; you have to design for it.
  • No native or touch-friendly controls
  • Best with smaller sites, probably wouldn’t scale for a web application

Testing Tools

Testing on real phones, while optimal, isn’t always an option. The next best thing is to use a simulator to test your mobile website. It takes quite an effort to find all the available simulators online, so I’ve compiled a list here:

Nokia (Symbian S60)- 5.0 is for touch devices, 3.0 is the latest for non-touch devices. SDKs can be downloaded here- http://www.forum.nokia.com/Library/Tools_and_downloads/Other/Symbian_SDKs/

Opera- simple Mac/PC versions of the Opera Mobile emulator are available for download and they have a web-based version of their Opera Mini Simulator. (http://www.opera.com/developer/tools/)

iOS (Apple)- Apple’s simulator is in their SDK and includes support for the iPhone and iPad. The SDK requires OSX to run. (http://developer.apple.com/devcenter/ios/index.action)

Blackberry- Blackberry simulators are available for download on their website and require Windows in order to run. (http://na.blackberry.com/eng/developers/resources/simulators.jsp)

Android- the Android SDK is available for Windows, OSX and Linux, which includes an excellent device simulator. (http://developer.android.com/sdk/index.html)

webOS (Palm/HP)- the Palm SDK is available for OSX, Ubuntu and WIndows computers on their website. (http://bit.ly/cl9jc1)

Microsoft- the 6.5 developer kit is publicly available, while nothing has been officially released for version 7 yet. Engadget ran a tutorial on how to get it running if you are anxious- http://www.engadget.com/2010/03/20/taking-the-windows-phone-7-series-emulator-for-a-test-drive-vid/

Firefox Mobile- the Firefox Mobile browser is a simple download for Windows, OSX or Linux computers on their website. (http://www.mozilla.com/en-US/mobile/download/)

In Conclusion

So it turns out building a mobile website in 2011 and beyond isn’t so bad. For the most part, mobile browsers now support HTML5 and CSS3 better than desktop browsers. Plus, there are all these open source frameworks to help you with the design and interactions. When it comes time to build your next mobile site, hopefully this article will eliminate the guesswork and help you make a great decision.

(rb)

December 17 2010

15:35

HTML5 and CSS3 Without Guilt


Not every HTML5 or CSS3 feature has widespread browser support, naturally. To compensate for this, enterprising developers have created a number of tools to let you use these technologies today, without leaving behind users who still live in the stone age.


Prologue

HTML5 Semantic Elements

The good news is that, except for Internet Explorer, you can create more semantic markup by using the new HTML5 elements — even in browsers which don’t officially support them. Just remember to set the correct display mode: block. The following snippet should reference all necessary elements:

article,aside,details,figcaption,figure,
footer,header,hgroup,menu,nav,section {
   display: block;
}

IE Conditional Comments

Implementing many of the solutions in this tutorial involves including some JavaScript for specific Internet Explorer releases. Here is a quick overview: the test expression is enclosed in square brackets. We can check for specific versions or versions above or below a stated version. lt and gt mean lower than and greater than, respectively, while lte and gte mean lower than or equal to and greater than or equal to.

Here are some quick examples:

[if IE 6]

Checks if the browser is Internet Explorer 6.

[if gt IE 6]

Checks for a version of Internet Explorer greater than 6.


Tool 1: HTML5 Shiv

In anything IE, excluding the most recent version (IE9), you cannot apply styles to elements that the browser does not recognize. Your spiffy, new HTML5 elements, in all their glory, are impervious to CSS rules in that environment. This is where Remy Sharp’s html5shiv (sometimes called html5 shim) comes to the rescue. Simply include it in your page’s <head> section and you will be able to style the new HTML5 elements perfectly.

<!--[if lt IE 9]>

<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

Notice how the conditional comments only load the html5shiv code on the condition that the version of Internet Explorer is lower than 9. Other browsers, such as Firefox and Chrome, will also ignore this tag and won’t execute the script, thus saving bandwidth.

html5 shiv is based on a simple workaround: it directs IE to create the elements with JavaScript (they don’t even need to be inserted into the DOM).

document.createElement('header');

At this point, they can be styled normally. Additionally, the more recent versions integrate IE Print Protector, which fixes a bug where the HTML5 elements disappear when printing the page..


Tool 2: Modernizr

Modernizr allows you to provide “backup” styling in browsers that do not support certain HTML5 and CSS3 features.

Modernizr is perhaps the best known of these tools, but it is also fairly misunderstood (the name does not help). Take a deep breath: contrary to popular misconception, Modernizr does not enable HTML5 and CSS3 functionalities in browsers that do not support them (although it does include html5shiv to allow you to use HTML5 elements in IE < 9).

Apart from the html5shiv functionality, Modernizr does one thing and one thing only: it runs a series of feature detection tests when loaded, and then inserts the results into the class attribute of the <html> tag.

Modernizr’s primary purpose is to allow you to offer “backup” styling in browsers that do not support certain HTML5 and CSS3 features. This is somewhat different than traditional graceful degradation, where we use the same CSS styling in all browsers, and then engineer it so that, when specific capabilities are missing, the result is still acceptable.

Now for an example of how Modernizr operates: if a browser supports border-radius and the column-count property, the following classes will be applied:

     <html class="csscolumns borderradius">

On the other hand, if the same properties are not supported — say, in IE7 — you will find:

     <html class="no-csscolumns no-borderradius">

At this point, you can then use these classes to apply unique styling in browsers with different capabilities. For instance, if you want to apply a different style to a paragraph, depending on whether CSS columns are supported, you can do:

  .csscolumns p {
    /* Style when columns available */
   }

  .no-csscolumns p {
    /* Style when columns not available */
   }

If a browser does not support columns, the .csscolumns class will not be present in the body, and the browser will never have a chance to apply the rule which uses it.

Some might object that this brings us back to the old times of building a different site for each browser. It is true that nothing stops you from writing so many style declarations that use advanced CSS3 features that your stylesheet becomes virtually empty when these rules cannot be applied.

If you want to use Modernizr in a way that makes sense, you must rely on your design talent to conceive alternative styles that don’t break the design and don’t require throwing away the rest of the stylesheet. For example, you might try replacing drop shadows on letters, when they are not available, with a bold typeface or transparency with a different color.

Usage

To use Modernizr, include the minified file, and apply a class of no-js to the <html> element. This last precaution allows you to provide styles for when JavaScript is completely deactivated; obviously, in those cases, Modernizr can’t help you at all. If JavaScript is enabled, Modernizr will kick in and replace the no-js with the results of its feature detection operations.

<head>
<script src="modernizr-1.x.min.js" type="text/javascript"></script>

</head>
<body class="no-js">
. . . . .
</body>

If you’re willing to accept that all websites needn’t display identically across all browsers, you’ll find that Modernizr is an essential tool in your web dev belt!


Tool 3: IE 6 Universal CSS

On the same note, designer Andy Clarke has devised an elegant solution for solving IE6′s lack of standard compliance. Called “Universal IE6″, this stylesheet focuses exclusively on typography. The key is to use conditional comments to hide all other stylesheets from IE 6.

<!--[if ! lte IE 6]><!-->
/* Stylesheets for browsers other than Internet Explorer 6 */
<!--<![endif]-->

<!--[if lte IE 6]>
<link rel="stylesheet" href="http://universal-ie6-css.googlecode.com/files/ie6.1.1.css" media="screen, projection">
<![endif]-->

Important Note: Remember to include the latest version, as instructions for older ones are still floating around the web. The final results looks like so:

Universal IE6 CSS sample result

You have zero work to do to support IE 6 on a new site.

This approach has a pretty obvious advantage compared to classical alternate stylesheets: you have zero work to do to support IE 6 on a new site. The disadvantage, of course, is that the site displays very little of your design. Further, your HTML foundations also has to be rock-solid, in order for the page to be usable even with most styling disabled.

Note that Universal IE6 CSS does not include any styling for HTML5-only elements such as <section> or <footer>. It is not a problem unless you are relying on those elements exclusively to obtain block level display for some parts of the page. Generally, you would always wrap your text also at least in a paragraph or list element.

This solution is clearly not for everybody, and you might find clients who flat out disagree with their site looking brokenwhen viewed in IE6.

You might also argue that, at this point, you can just as well drop IE6 support entirely. Andy Clarke has summarized his answers to these objections here.

This approach works best for content-centric sites, and catastrophically for web applications; but then again, building a modern web application to work well on IE 6 is a challenge in itself.


Tool 4: Selectivizr

Selectivizr Support

Our next champion is a JavaScript utility which aims to introduce new capabilities into older browsers (well, actually just IE 6-8): Selectivizr works in tandem with other JavaScript libraries such as jQuery, Dojo or MooTools to add support for a range of more advanced CSS selectors.

I’ve listed a few below, though note that the full list of capabilities will be dependent upon your preferred JavaScript library.

  • :hover
  • :focus
  • :first-child
  • :last-child
  • :first-line
  • :first-letter

To use Selectivizr, download it from their home page and include it within your <head> section, together with one of the support libraries. Here is an example with jQuery:

<script src="jquery-1.4.4.min.js"></script>
<!--[if lte IE 8]>
  <script src="selectivizr.js"></script>

 <![endif]--> 

Selectivizr works in tandem with other JavaScript libraries to provide CSS3 support for IE 6-8.

This point is very important: Selectivizr cannot work alone; it requires your preferred library to be present. Luckily, it is compatible with the huge majority of popular JavaScript libraries. Chances are, if you are using JavaScript on your site, you probably have an appropriate library already included.

DOMAssisant

On the other hand, if you won’t be using a library as well, an alternative solution is to use the light weight DOMAssistant, although you might still prefer your usual JavaScript library for greater ease in managing files.

Be careful though, as the precise selectors that Selectivizr makes available depends on which supporting library is chosen. According to the home page, right now the greatest range of selectors is available with MooTools, while unfortunately jQuery makes the least number of selectors available. It must also be said that some of the selectors that are not available with jQuery are quite exotic and rarely used in the real world usage. Refer to our “30 CSS Selectors you Must Memorize” article for a full list of selectors.

As it happens, with most JavaScript solutions for CSS woes, some restrictions apply.

  • For Selectivizr to perform its magic, stylesheets must be loaded from the same domain as HTML pages. This rules out, for instance, hosting stylesheets and other assets on a CDN.
  • You are forced to use the <link> element to include your stylesheets (as opposed to <style>).
  • Selectivizr does not update styling if the DOM changes after the page has finished loading (if you add elements in response to a user action, for instance).

Tool 5: CSS3Pie

CSS3Pie also enhances Internet Explorer’s [6-8] capabilities, but in a much more native way, as it effectively enables the use of a number of spiffy CSS3 properties, like border-radius, linear-gradient, box-shadow, border-image as well as adds support for multiple backgrounds. Use CSS3Pie and say goodbye to manually sliced and positioned rounded corners.

CSS3Pie: say goodbye to manually sliced and positioned rounded corners.

The way it works is by leveraging little known proprietary Microsoft extensions: the CSS behavior property and HTML component files (official documentation). This extension allows you to attach JavaScript to certain HTML elements using CSS. The JavaScript is included together with some Microsoft proprietary tags, in .htc files which are referenced within the style rules.

For this reason alone, many developers might argue that you shouldn’t use CSS3Pie. Internet Explorer’s proprietary tags are performance heavy and produce less-attractive output.

Why doesn’t CSS3Pie use plain JavaScript? Well there is a JS-specific version, though the team advises against its usage, due to the fact that the JavaScript blocks the parsing of the page.

With the current .htc solution, implementation is quite simple: you only need to upload a single file from the CSS3Pie distribution, PIE.htc, to your server. Afterward, every time you use one of the supported CSS3 properties, add the code below:

behavior: url(path/to/PIE.htc);

Above, path/to/PIE.htc is the path, relative to the HTML file being served; not the stylesheet.

Server Side Instructions

Of course, CSS3Pie can only do its magic in Internet Explorer. It also needs a bit of care and feeding on the server side:

  • You should ensure that the PIE.htc file is served with a text/x-component content type. The distribution includes a PHP script that can take care of this if you are not allowed to modify your server configuration, for instance on a shared host.
  • PIE.htc can also trigger ActiveX warnings, usually when you are testing it on your localhost. This last problem requires the Mark of the Web workaround to be solved.

CSS3Pie is still, at the time of this writing, in beta mode – as there are still some kinks to be ironed out.


Tool 6: HTML5 Boilerplate

HTML5 Boilerplate goes much further than your standard starter templates.

HTML5 Boilerplate can be described as a set of templates to help you get started building modern HTML5 websites as rapidly as possible. But HTML5 Boilerplate goes much further than your standard starter templates.

For instance, it bundles the latest version of Modernizr (same creator), and the HTML even links to the latest Google-hosted jQuery, Yahoo profiler and Google Analytics scripts for you. The CSS contains the usual reset rules, but also a wealth of @media queries to get you started with responsive web design targeting mobile devices.

Configuration Files

The most unique feature is that, on top of client configuration, you also get the server side: configuration files for Apache and Nginx. This allows you to maximize download speeds and optimize HTML5 video delivery. In particular, the .htaccess files for Apache might be very convenient to drop into a shared hosting account, as often things like gzip compression and expires are not active by default.

Does it do too Much?

Some people might argue that HTML5 Boilerplate takes a bit too many decisions for them (hell, the Apache configuration even automatically strips www. in front of the domain name!) or that it is somewhat Google-centric, though, nonetheless, it’s always interesting to study the files and find what problems the authors have anticipated.

Further, you’re certainly encouraged to break it down for your personal needs. This is simply a boilerplate to get you started.

A Visual Overview

If you want a detailed breakdown of everything HTML5 Boilerplate includes, Paul Irish recorded an exclusive screencast for Nettuts+.

A fully commented version is available at html5boilerplate.com.


Epilogue: Be Bold

Often, the fear of implementing features which do not enjoy full browser support discourages designers from adopting the latest technologies. While the demographics of your audience has to be considered carefully, as well as your client’s wishes, if you accept that sites don’t have to look the same in all browsers, it is possible to make full use today of HTML5 and CSS3.

Think of it this way: if you wait until CSS3 “is complete,” you’ll be waiting forever. CSS2 isn’t even fully supported across all browsers yet! The guiding principle here is that every user should get the most bang for his buck: if he is using a bleeding edge browser, why not take advantage of all the features that browser provides?

Let us know what you think about these issues in the comments. Thank you so much for reading!

November 24 2009

10:30

Building an Image Gallery with Progressive Enhancement

Who doesn’t love to completely trick out their website with neat features? But what happens when your viewers aren’t using the latest browser, or they have JavaScript turned off? In today’s tutorial, you’ll learn how to create a image gallery that will work in almost all environments, using progressive enhancement techniques.


Introduction

Final Product

So what exactly is progressive enhancement? Formally, it is this:

Progressive enhancement is a strategy for web design that emphasizes accessibility, semantic markup, and external stylesheet and scripting technologies. Progressive enhancement uses web technologies in a layered fashion that allows everyone to access the basic content and functionality of a web page, using any browser or Internet connection, while also providing those with better bandwidth or more advanced browser software an enhanced version of the page. (Wikipedia).

Progressive enhancement is the opposite of graceful degradation, where you build your site/app with all the features, and then make sure it looks good and functions decently in older browsers. With progressive enhancement, we’ll lay a solid foundation for our image gallery that will work no matter where you view it. Then, we’ll layer on eye-candy and functionality until we’ve got a good-looking, well-functioning image gallery. Let’s begin!

What we’re After

Here’s what we want to end up with: if all the bells and whistles are turned on, we’ll be able to drag our images around to view them; it will be a very basic simulation of a stack of photos on your coffee table. When you click on one, it will slide open to reveal some details about the image. If JavaScript is turned off, we’ll have a nice grid of image to choose from; clicking them will take us to a page with a larger version of the image and the details. If there’s no CSS support, we’ll get an ugly (but working) list of the images.

Here’s a screen-shot of our final product:

Screenshot of finished gallery

Laying the Foundation: POSH

We start with some plain old semantic HTML. This is our foundation, since every browser out there is good at parsing HTML.

index.htm

<!DOCTYPE html>
<html>
<head>
	<meta charset='utf-8' />
	<title>Progressively Enhanced Image Gallery</title>
</head>
<body>
	<div id="container">
			<h1>Click on an image below to view it!</h1>

		<ul id="images">
			<li><div>
				<a href="3dOcean.htm"><img alt="3dOcean" src="images/thumbnails/3dOcean_tn.jpg"/></a>
			</div></li>
			<li><div>
				<a href="AudioJungle.htm"><img alt="AudioJungle" src="images/thumbnails/AudioJungle_tn.jpg"/></a>
			</div></li>
			<li><div>
			<a href="ActiveDen.htm"><img alt="ActiveDen" src="images/thumbnails/ActiveDen_tn.jpg"/></a>
			</div></li>
			<li><div>
				<a href="GraphicRiver.htm"><img alt="GraphicRiver" src="images/thumbnails/GraphicRiver_tn.jpg"/></a>
			</div></li>
			<li><div>
				<a href="ThemeForest.htm"><img alt="ThemeForest" src="images/thumbnails/ThemeForest_tn.jpg"/></a>
			</div></li>
			<li><div>
				<a href="VideoHive.htm"><img alt="VideoHive" src="images/thumbnails/VideoHive_tn.jpg"/></a>
			</div></li>
		</ul>

	</div>
</body>
</html>

That’s it; pretty basic stuff, eh? No browser worth that title should have a problem with it. And this is our finished first layer. No, it’s not pretty, but that wasn’t our goal: we wanted something that will work everywhere, no matter what. A few things to notice about this code: firstly, it’s semantic, as we said it should be. You might wonder about the divs inside the list items. What’s up with them? Even though we’re starting with the bare bones, we are anticipating that most of our viewers will have JavaScript enabled, in which case we’ll need those divs. We could insert them with jQuery, but since we do expect them to be used most of the time, it’s easier to hard-code it in. The other thing to notice is that it’s usable. Try viewing it in Lynx, or another text-only browser:

Gallery in Lynx

By the way, the pages linked to in the HTML above will be available in the downloadable source; they’re all similar to this:

<!DOCTYPE html>
<html>
<head>
	<meta charset='utf-8' />
	<title>Themeforest MarketPlace by Envato</title>
</head>
<body>
<h1>ThemeForest</h1>
<img src="images/ThemeForest.jpg" alt="ThemeForest" />
<p>Themeforest offers: HTML Templates, WordPress,
Joomla, Flash Sites, PSD Templates, Javascript, PHP Scripts</p>
</body>
</html>

On a real site, you’d surround this with your site template, but it’s just fine for our purposes.

Dressing the Structure: CSS

Although semantic HTML is nice, it looks a bit bare. Let’s dress it up with some CSS. Of course, we first have to reference the stylesheet:

<link type="text/css" rel="stylesheet" href="styles/default.css" media="screen" />

We’ll level the playing field first with a stripped-down Meyer reset:

/* Meyer's Reset */
html, body, div, h1, h2, h4, p, a, img, ul, li
{ margin: 0; padding: 0; border: 0; outline: 0; font-weight: inherit; font-style: inherit; font-size: 100%; font-family: inherit; vertical-align: baseline; }
/* remember to define focus styles! */
:focus { outline: 0; }
body { line-height: 1; color: black; background: white; }
ol, ul { list-style: none; }
/* END Meyer's Reset */

Now we have to style our gallery for use without JavaScript. We’ll start with some general elements and background styling:

body{
	font:13px/1.5 'Helvetica Neue',Arial,'Liberation Sans',FreeSans,sans-serif; /* <-- from 960.gs text.css */
	background: #36b4dd;
}
h1 { font-size: 30px; }
#container > h1 { padding: 10px;}
h4 { font-size: 20px; padding-bottom:10px;}

Now we’ll take care of our heading and list items.

#container h1 {
	padding: 10px;
}
#images li {
	float:left;
	background:#ececec;
	border:1px solid #ccc;
	margin:10px;
	width: 256px;
	padding: 10px;
	overflow: hidden;
}
#images li div {
	width: 512px;
	overflow:hidden;
}
#images li a {
	float:left;
}
#images li div.info {
	width: 246px;
	padding:0 0 0 10px;
	float:left;
}

You’ll notice that we’ve set a width on our list elements. We need to do that for our JavaScript functionality; that’s also why overflow:hidden is set. This is easy in our case, because I’ve made all the images the same width. If yours are different widths, you’ll probably have to set the width for each list item with JavaScript. That will work because the CSS only version doesn’t require the width. The div directly inside our list item (that wraps all the content) is 512px wide, with overflow hidden. We’ve floated our anchor to the left so we can float the div.info to the left beside it, as you see further on.

So, here are the fruits of our labours so far:

Our Gallery with CSS only

We’ll come back to CSS in a bit; but now, let’s turn to the JavaScript!

Adding the Functionality: JavaScript

We’ll be using jQuery here; so start by importing that from Google’s CDN. We’ll also need the jQueryUI library. We could get that from Google as well, but we don’t need the whole library. I’ve downloaded a copy from the jQueryUI site, with just the core and the draggable components, which is all we’ll need. You can do whichever you prefer.

<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js'></script>
<script src='js/jqueryui-core-drag.js'></script>

Before we start coding, let’s determine what we need to do.

  • The h1 we’ve hard-coded provides instruction for the non-JavaScript version. We’ll remove this and add different instructions.
  • We need to configure the dragging on the list elements; we’ll add a splash of fun: when the user releases the list item, it will slide a bit further and slow down (sounds like an iEffect). Like we said earlier, it’s supposed to be somewhat like a stack of photos on a table.
  • When a list item is clicked, it should ‘slide open,’ doubling in width. Before it does, however, we’ll send an Ajax call to get the page that the user would go to if JavaScript wasn’t enabled. Then, we’ll get the values we want from that page and plug them into our list item in a div. We’ll check for this div before making the call, though, so if the user has already clicked on it, we won’t send another request.

Alright, open up a script tag and let’s code!

var imgs;

$(document).ready(function () {

});

$(window).load(function () {

});

We’ll start by creating a global variable: an array of the list items (well, it will be an array soon). Then, we set up event handlers for a) when the DOM is ready, and b) when the window is finished loading. The effect we’ll do when the window loads (which I haven’t told you about yet) doesn’t require that we wait until then, but I think it will be nicer when the images have been loaded.

Now, this code goes in our document.ready function:

var  drag = {};
$('h1').remove();
$('#images').append('<li id='instructions'><h2>Toss the images around; if you see one you like, click on it!</h2></li>');

imgs = $('#images li');

Should be straightforward: we create an object that will hold some details about out dragging; then we remove the h1, append a list item with new instructions to our list, and put all the list items in our imgs variable.

Now we’ll build our dragging functionality. Really it’s as simple as this:

imgs.draggable();

But we’re going to add a few options. Here’s the code; persue it yourself and then we’ll stroll through it.

imgs.draggable({
			stack : { group : '#images li', min : 1},
			start : function () {
				$this = $(this);
				if($this.attr("id") === 'instructions') { $this.fadeOut().remove(); }

				imgs.each(function () {
				var $this = $(this);
				if($this.width() !== 256) {
					$this.stop().animate({width : 256 }).removeClass('top');
				}
			});

			drag.startTime = new Date();
			drag.startPos = $this.position();
		},
		stop : function () {
			var $this = $(this), top, left, time;
			drag.endTime = new Date();
			drag.endPos = $this.position();
			drag.leftOffset = drag.endPos.left - drag.startPos.left;
			drag.topOffset  = drag.endPos.top  - drag.startPos.top;

			time = (drag.endTime.getTime() - drag.startTime.getTime()) /60;

			top  = (drag.topOffset / time).toString();
			left = (drag.leftOffset / time).toString();

			$this.animate({
				top : '+=' + top,
				left: '+=' + left
			});
		}

});

We’ve added three properties to our draggable options object: stack, start, and stop. Stack controls the z-index of a group of objects, and takes an object with two properties of its own: group and min. Group is a jQuery selector; in our case, it’s the list items. Min is the minimum z-index any items in the group can take. So now, when you drag an item, it comes to the top of the pile.

The start function is run when you begin to drag an item. We start by caching $(this). Then, we check to see if the list item we grabbed has an id of ‘instructions.’ If it does, we fade it out and remove it. Then, we loop over each list item and if we find any that aren’t 256px wide, we animate the width to 256px and remove the class of ‘top.’ What’s ‘top’ do? We’ll style it in a few minutes, but it just gives the user some visual feedback when they click an item. After that, we do something very important: we set two properties on our drag object. One (startTime) is the time the dragging started, and the other (startPos) is the position the item started at. We’ll use this information to create our effect when the dragging stops.

Lastly, we have the stop function, which predicably runs when user stops dragging. Again, we start by caching $(this), as well as creating a few other variables we’ll give values to in a moment. Next, we put our end time and position into drag.endTime and drag.endPosition. Then we calculate our left and top offset by subtracting where we were from where we are; we can do this with the top and left properties that the position object has. Now for the slowing down animate logic: you could get very complicated with this algorithm, but we’re just going to keep it simple. We’ll find the time the drag took by subtracting our startTime from our endTime; the getTime method returns the number of milleseconds since 1970/01/01, so the difference is in milleseconds Then, we divide that value by 60, which I came up with through trial and error. On an average drag, this sets our time variable somewhere between 2 and 3. Then we divide our top and left offset by time, and convert those values to string, saving them in top and left. Finally, we animate the dragged list item, incrementing (that’s what ‘+=’ does) the value by top or left. At this point, you should be able to drag the images around and get our effect.

However, clicking the images will bring you to a new page. So let’s set up our click event handler.

imgs.click(function () {
			var $this = $(this);

		if ($this.attr('id') === 'instructions') {
			$this.fadeOut().remove();
		}
		else {
			if($this.width() !== 256) {
				$this.stop().animate({width : 256 }).removeClass('top');
			}
			else {
				if (!($this.find('.info').length)) {
					$.ajax({
						url : $this.find('a').attr('href'),
						dataType : 'html',
						success : function (data) {
							var $d = $(data),
								head = $d.filter('h1'),
								para = $d.filter('p');

							$this.children('div').append('<div class="info"></div>').find(".info").append(head, para);
						},
						error : function () {
							var msg = '<h1>Oops!</h1><p>It looks like there been a problem; we can\'t get this info right now.</p>';
							$this.children('div').append('<div class="info"></div>').find(".info").html(msg);
						}
					});
				}
				$this.css({'zIndex' : 8 })
					 .stop()
					 .animate({ width : 512})
					 .addClass('top')
						.siblings().removeClass('top')
								   .stop()
								   .animate({width : 256})
										.filter(function () { return $(this).css('zIndex') === '8' }).css({'zIndex' : 7});
			}
		}
		return false;
	});

Standard operating procedure today: begin by caching $(this). Once again, we check for the id of instructions; if it’s there, we fadeOut and remove the item. If its not there, we check the width of the element: if it isn’t 256px, that means this item has already been clicked, so we animate the width down to 256 and remove our top class (yes, we’ll get there). If the element is 256px wide, we check for a child element with the class of info. We can do this my calling the find method on the element, pass in the selector we’re looking for, and get the length property. If this element doesn’t exist, the result will be 0, which is a false value, so we wrap that in parentheses and use a ! to switch the boolean. Now, if there aren’t any child elements with a class of info, we’ll step into this block, which is our ajax call.

$.ajax() takes an object parameter, and we’ll use four properties: url, datatype, success, and error. Url and datatype are obvious: we simply find the anchor in our list item and set url to its href; our datatype is html. If our ajax call is successful, we’ll take the data we get, which is the entire HTML contents of the page, and turn it into a jQuery object. Then, we can filter out the heading and paragraph that we know we have there. Then we simply get the div inside our list item, append a div.info, and append the heading and paragraph to that. If our request fails, we’ll show an error message by a similar process, using the error function. After our ajax call, we want to perform some styling and animation on our list item. First, we want to set the z-index to 8, or any number higher than the number of draggable items we have. Then we want to stop all current animations on this list item and animate the width to 512px. Lastly, we’ll add that top class. Next, we get all the siblings, which are the other list items. We’ll stop any animation on them and then animate them to 256px wide. Finally, we’ll filter out only the elements with a z-index of 8 and change their z-index to 7. This allows the currently cliked list item to come ot the top. Right at the end, we return false, so we stay on our current page (because even though this is a click function on a list item, the users will most likely click our anchor-wrapped image inside the list item).

So that’s our click handler; only one piece of JavaScript left. If you give our example a try now, you’ll see it works … kind of. Whenever you click a list item to open it, it opens, but you’ll notice a rather shifty problem. It’s because the list items are floated to the left; let’s take care of that in our window ready handler.

$(window).load(function () {
	var $w = $(window);
	imgs.css({	position : 'absolute',
			left : $w.width() / 2 - imgs.width(),
			top  : $w.height() / 2- imgs.height() });
	for(var i = 0; imgs[i]; i++ ) {
		$(imgs[i]).animate({	left : '+=' + Math.random()*150,
						top  : '+=' + Math.random()*150 });
	}
});

If you’ve followed pretty well so far, you won’t flinch here: we simply use the jQuery’s css method to set the positioning to absolute and stack all the images so their right edges are aligned to the middle of the viewport, and their bottom edges are aligned to the vertical middle. Then we use a for loop to recurse over each list item and randomly animate it right and down. This creates the effect of a stack of images being scattered.

So that’s it for the JavaScript! Now, when a user loads the page, they should see something like this (after animation) :

Images scattered

Final Touches: CSS3

We could end there, but we want to reward those who use forward-thinking browsers, so it’s back to the CSS for a few minutes. And, yes, we’ll look at the top class.

The first thing we’ll do is add rounded corners to the selector #images li.

border-radius:5px;
-moz-border-radius:5px;
-webkit-border-radius:5px;

Then the top class, which list items only have when they are ‘open,’ looks like this:

.top {
	box-shadow:0 0 10px #000;
	-moz-box-shadow:0 0 10px #000;
	-webkit-box-shadow:0 0 30px #000;
}

Nothing incredibly fancy, but a few nice refinements nonetheless.

Closing Comments

Well, that’s it. We should now have an image gallery that works decently without CSS or JavaScript, but takes full advantage of them where those technologies are available. So, how would you improve our gallery? Let’s hear it in the comments!


Older posts are this way If this message doesn't go away, click anywhere on the page to continue loading posts.
Could not load more posts
Maybe Soup is currently being updated? I'll try again automatically in a few seconds...
Just a second, loading more posts...
You've reached the end.
(PRO)
No Soup for you

Don't be the product, buy the product!

close
YES, I want to SOUP ●UP for ...