em, and the two zooms

Back in the days before browser “zoom”*, making text bigger on the page was done by incrementing all the font sizes in the document. All fonts set at 16px became, for example 18px, and all fonts at 20px became 22px.

The problem with this was that often text would outgrow the element it appeared in, because the element was also given a width and height in pixels and this didn’t get scaled as the text size increased or decreased.

Sometimes even if you built a site that allowed text to grow and wrap, it would get to a stage where a single long word was wider than its container, and the overflow would have to either be hidden, or just left visible to run into whatever element was placed on the immediate right. Not only that, but there are just some situations where you don’t want elements to wrap – whether they’re text nodes, floated elements with text in them, or inline-bock elements that you often find in navigation lists.

We didn’t want text zoom, we wanted magnification zoom i.e. the zoom that we have nowadays…but it didn’t exist.

Em to the rescue! Luckily, the em unit is intrinsically linked to text size. It is a relative unit, meaning that the actual size of an em depends on the font-size of its container. Clever people figured out that you could simulate magnification zoom if you measured all your widths and heights using relative units.

How does that work?

Well, if your font sizes are all increased, and everything else is measured in em’s (the width of the letter ‘M’), then everything else gets bigger as well, in proportion. Hooray!

Sure, but why would we use them nowadays?

Firstly, if someone is using an old browser that doesn’t support magnification zoom, or is using the (still existing) older text size zoom, you don’t get the problems I’ve just described above that are inherent to text zoom.

Secondly, if you never define an absolute text size for your document, your viewers are free to set their own default text size (On Firefox you can do this by visiting preferences > content > fonts & colours), and your layout will change size to accommodate. Almost all browsers set their text size at 16px by default, so if you use this as your base – i.e. 16px = 1em, then your site will be the size your designer is probably expecting it to be.

I use em’s for almost all units that could also be expressed in pixels, or percentages or whatever. Percentages almost certainly have a very important place as well, but unless you’re working with a fluid design they’re not a necessity.

* Which, for your reference, works by changing the definition of how big a pixel is on your screen. It means you’re really working with points, not pixels, but that’s by the by.

Hardware accelerated alternative to jQuery animate() top, left, width, height and opacity CSS properties for iPhone/iPad

I was recently asked to quote for a proof of concept HTML5 alternative to a flash carousel, specifically to run on iPad. I said I’d do it, but the agency later decided that others had tried to create a HTML5 version and had not been able to create a version that performed well enough for the client. From my point of view they were under the impression I couldn’t do any better. So naturally, I spent a few hours of my spare time proving this wrong, just for the fun of it.

Step 1 was to build a version of the carousel in HTML5. I chose to use the jQuery framework because…well, I felt like it. The fruits of my labour are here:

http://freestyle-developments.co.uk/demo/public/portsurf/

Now, you can view this on any browser. All that is happening is that there are a set of list items absolutely positioned in a container, when you click/touch an item on the left/right jQuery animates the top, left, width, height and opacity CSS values for each item.

Fantastic, but, it feels really sluggish on iPad and iPhone 4. Go on, try it out.

Fair enough, they are resource constrained devices. What to do though? I’ve already used all the tricks I could think of fast loops, select operation caching etc. etc. So what now?

Luckily, in iOS, transitions and animations of the -webkit-transform and opacity properties are performance-enhanced. Sweet! These correspond exactly to the two CSS properties I’m trying to manipulate for each item in my carousel. Implementation was a simple case of swapping out the jQuery animate function, for the css function. Passing in the webkit transition, webkit transform and opacity values in its place.

For example:

items[itemIndex - 3].css({
	opacity:1,
	'-webkit-transform':'translate3d(' + carousel.itemPosition.medium.left.x 
            + 'px, ' + carousel.itemPosition.medium.left.y + 'px, 0) scale(0.5)',
	'-webkit-transition':'opacity 0.4s linear, -webkit-transform 0.4s linear'
});

The webkit transition property is saying “transition these CSS properties from what they were previously to their new values, using these transition parameters (0.4s linear)”. The webkit transform property is saying “move this element to the following coordinates, and scale it by a factor of 0.5″.

Check out the hardware accelerated version on your iPad/iPhone and compare it with the other:

http://freestyle-developments.co.uk/demo/public/portsurf/?ha=1 (Note: webkit only)

Here is a video demonstrating the performance differences those of you without iPads.