Jul 11

Building a Touch-Friendly HTML5 Site

It Looks and Acts like an App…but it’s a Website

Over the past month I have been doing some experiments with html5 and JavaScript. Specifically, I wanted to see exactly how close I could come to making a website ‘feel’ like a native app.

In a recent post I made a claim that “websites can take a lesson from apps”. By which I meant, that apps do a better job of delivering curated content and rich interactivity than most websites currently do. So with that in mind I set out to create a sample website that featured some app-like functionality. Along the way I discovered some things I’d like to share:

  • Avoiding jQuery has some perf benefits for mobile devices
  • Adding Touch support, and handling the default behaviors
  • Getting around the lack of native scrolling in a fixed layout on iOS.
  • Using RequestAnimationFrame to conserve resources
  • Taking advantage of Hardware acceleration where it makes sense

Demo Site & Code

If you’re like me and don’t have the patience to read the full post, I’ll cut to the chase. The sample website demonstrates how to do the following:

  • Avoiding the use of jQuery for optimized perf on mobile devices
  • Adding touch capabilites to screen elements
  • Using hardware accelerated css animations
  • Detecting browser capabilities with Modernizr
  • An inertial scroller to workaround the lack of native scrolling in a fixed layout on iOS

Avoiding jQuery for Better Performance

jQuery is great, I use it all the time and in this day of browsers being riddled with discrepencies it makes web development much less of a headache. However, jQuery can be a bit bloated when you are building sites that are targeted for mobile devices. Mobile devices, even the best ones, just don’t have the horse power to run rich websites like laptops and desktop computers. Fortunately, the modern browser and especially thier mobile counter parts have made long strides in the realm of performance and functionality, and to some degree eliminate the need for large js libraries. While doing some research on the topic of “to Query’ or not” I stumbled upon a couple great links demonstrating some of the perf benefitts of avoid jQuery.

Long story short, a lot of websites only leverage selectors, $.ready, and event binding capabilities of jQuery. And the mobile browsers that support javascript implement the W3C HTML5 spec fairly well. Making it relatively easy to hand roll some js utilities to mimc what jQuery does without the added weight of the rest of the framework. Specifically, jQuery does a lot of scrubbing and checking behind the scenes that can send 1 line of code down a muti-step code path. While building the sample site I found these links helpful:

Adding Touch Support

In case you have been living under a rock, many of the recent mobile browsers can propagate touch info similar to how mouse info is bubbled up to javascript. In most simple cases, say handling click events, you won’t need any of the extra touch information. But for more advanced interactivity like scale, rotate, flick-able scrolling, the touch information is crucial.

In this case I needed to add some inertial scrolling (which I’ll talk about more below). I already had it working with the mouse, and I didn’t want to duplicate all the code for touch. So I added a pretty clean way to handle the touch events by passing the touch info into the existing mouse handlers:

[gist id=1104360]

Preventing the Default Scroll and Page Scale
Lastly, if you decide to handle touch events coming from the browser you have to take one additional step to ensure that the default behaviors of iOS don’t fire when you’re executing your code.

To prevent the default pinch & zoom and the elastic scrolling functionality of the iOS browser add this line to your HTML page:
[gist : id= 1104517]

In general I think touch support rocks and provides very accurate real-time information about all the contact points in the browser. While building the sample site these links were most useful to me:

No Native Scrolling in a Fixed Layout in iOS

This isn’t really a new thing. In fact, there has been quite a bit of discussion about this around the interwebs. Basically, if you have a fixed lay out, say 1024×768, and you have long content in the middle, iOS will NOT scroll like you might expect. So the only solution is to create your own scroller implementation….which isn’t the easiest thing in the world. Luckily there are some folks out there that have some pretty decent ones:

But being the anal retentive person I am, I decided to take a stab at writing my own. I had most of the code from a parallax control I wrote for WP7 last year. I also added some easing logic inspired from this cool HTML5 TRON site:

I tried to make the scroller as generic as possible. It uses CSS3D Transforms when it can to leverage hardware acceleration on iOS and Safari. You can download the entire sample site to see how its working, but if you’re just interested in the scroller I put it here:

Using RequestAnimationFrame

Until very recently, most people did animation in javascript by kicking off setInterval or setTimeout then incrementing the various object properties. This doesn’t work great when you are trying to animate a lot of objects on the screen at once. Enter RequestAnimationFrame – basically what this little gem does is queues up as many paint functions as it can into one tidy screen draw. Therefore you can save a considerable amount of cycles and cpu usage by opting to use the RequestAniFrame over timers. This is the implementation I went with from Paul Irish:

[gist: id=1104582]

If you’re are trying to push the bounds of what browsers can to, I highly recommend using the Request Animation Frame if your browser supports it. Currently, IE9, Opera, FireFox 5, Safari, Safari Mobile and Chrome 10 all support it. It offers a way to do much higher-fidelity animations than the current timer scenario. If you’re interested in learning more these are some great links:

Hardware Accelerated Animations

In my opinion, this is the secret sauce to making web apps ‘feel’ like native apps. And I’m sure it won’t be long before all the browser vendors hardware accelerate animations and transforms.

At the time of this writing, only a couple (safari/mobile safari) browsers hardware accelerate ONLY 3d CSS animations & transforms. Leveraging CSS Transitions and Animations can make or break the performance on mobile devices. By sending the animations to the GPU you can get a full 60fps for animations even on small devices like the iPhone. Run the sample site in Safari, or an iPad, scale up an image by clicking/tapping it to see the smooth hardware acceleration in action.

In the Sample Site I detect if CSS3d transforms are supported with Modernizr and then either transform objects with hardware accelerated css3d or fall back to regular 2d css transforms. The pattern I used in the sample looks like this:

[gist: id= 1104800]


The key here is the fact that safari and safari mobile hardware accelerate any CSS3d transforms and animations. In general I found it pretty easy to work with CSS Transitions passing 3D transforms in as my animation property. Check out the full source to see the nitty gritty, but in general a barebones css3d transition with hardware accelerated transfoms looks like this:
[gist: id= 1104856]

The best place to learn about css animations and transitions is on apple’s web developer site. While I was building the sample, these were the sites I found most useful:

My 2 Cents

Phew! That was an overwhelming amount of code and babble. If you hung in there and read through the whole thing…I hope it was informative. It took me about 3 weeks to wrap my head around all of it, so hopefully this will save some time for anyone looking to get up and running quickly.

Overall I think it takes quite a bit of finesse to build ‘app-quality’ websites that work reliably across all the modern browsers. And until the discrepancies between browsers are minimized or tools/frameworks pop up to handle some of these advanced features I don’t see a ton of value in going to the extreme to build premium website that work on all platforms.

As an alternative, I think it probably makes sense to land somewhere between a native app and a nice website. In other words, I think you can still create atypical and engaging websites that have some app-like characteristics, without having to fret about hardware accelerating every animation and falling back where there is no support. However, this is something that should be left to the technologist/designer to be decided on a case by case basis.

There are some really great examples of what I mean listed here:


Erik Klimczak | |

Comments Off , permalink

Tagged ,

Comments are closed.