Writing HTML and CSS for Mobile Safari. Just the same old code?

3 minute read

30 Aug 2010

The answer is "kind of". I'm a believer of the "write once, deploy anywhere" attitude. I'm also a big fan of things like WhitherApps; James has done a great job taking the (native) BBC News app and rebuilding it using just HTML and CSS to prove out this very concept.

BUT... people would be lying if they told you it's exactly the same as writing CSS for desktop browsers. It just isn't.

No support for the CSS fixed position

You could be forgiven for thinking that it just reverts back to absolute positioning like it does in IE6, but in fact it is not same as explicitly setting an element to absolute. The behaviour is subtly different, and I found that running any CSS3 style webkit transitions were much more performant, and less 'flickery' on an element with fixed position, over one with absolute even though the layout was identical.

Very strange considering there's no support for fixed position. Couldn't find that one in the specs anywhere either, so I remain baffled. My solution was to try both position attributes and see which performs better.

Usually though, Cubiq's iScroll will do the trick as it's more than likely the reason for needing fixed positioning anyway. That plugin genuinely works well by the way. Use it.

Hardware accelerated CSS transformations... but are they, really?

This one took me a good few hours to work out when I could have been quite happily doing far more productive things with my day. I knew already that the '-webkit-transform' and 'opacity' attributes were hardware accelerated for webkit transitions. If you're experiencing a flicker with css3 transitions, this is how to fix it.

It is true that opacity is hardware accelerated. It is also true that -webkit-transform is hardware accelerated, but, if you're using translateX, translateY or translateZ, you don't get that luxury. Take a typical CSS transition;

#element {
    -webkit-transition: -webkit-transform 1s linear;
    -webkit-transform: translateX(0);
}
#element.transformed {
    -webkit-transform: translateX(300px);
}

In any webkit browser, you'll get whatever #element is to move 300 pixels to the right, in a linear 1 second animation. On Mobile Safari, it will likely 'flicker' before/during/after the transition. The key is to use translate3d(x, y, z). The simple change shown below makes all the difference.

#element.transformed {
    -webkit-transform: translate3d(300px, 0, 0);
}

It's ridiculously simple, but honestly why would that be hardware accelerated and not the shorter hand, translateX property?

Avoid Javascript Libraries

You'll notice that the Javascript engine on the iPhone is incredibly slow. The iPad is greatly improved but its still advisable to minimise Javascript, particularly for things like animations. Always use a translate transition over animating the left or top properties. The CSS3 transitions are perfectly smooth and look great. Arguably you don't need jQuery for mobile apps as a lot of 'weight' comes from dealing with cross browser differences; obviously not being an issue if we're focussing solely on mobile webkit. With the new CSS selector engine, document.querySelectorAll(); you still get lightening fast 'jQuery style' DOM selections. Time to brush off the raw Javascript skills (or just be lazy and wait for jQuery mobile).

Am I being impatient?

There's only a handful of cases that have proved to be quite time consuming during development, but the point here is a bigger one.

The whole idea of unifying standards across all devices is the way forward. The thing is though that I can't help feeling that we're harking back to the "Are you using Netscape or Internet Explorer?" days. I wish we didn't have to know about these tricks. It means that without position fixed, we need to use (and write) Javascript extensions to help us out, but then we add weight and potential bugs to the desktop side of things. Do we really have to start detecting whether we're on an iPad and serve up specialised code? What about sites that we wrote before all this came about?

I'm still behind the idea of using HTML powered apps with simple Objective-C wrappers to encase everything into a native application. With a bit of reading up, and more than one or two stabs in the dark, its definitely not impossible to make an HTML driven app "feel" just as native as any other.

I guess one just has to accept that the concept of using exactly the same code on mobile and desktop devices still isn't quite there.

Updated: