Blog

Resolution Independent Mobile UI

…or… A pixel is not a pixel.
In my last article about the benefits of SASS and CSS3, I briefly touched on a technique we use in Sencha Touch to make our interfaces resolution independent. Today I will be expanding on that technique, so you can start to make your own scalable UI elements for WebKit.

A Brief Introduction

This is not an article on adaptive layouts or responsive web design. This article is specifically about pixel “density”, a relatively new concern to digital designers. In the mobile environment, screen resolution has been quickly advancing, resulting in larger and larger “pixels per inch” (ppi).
Take, for example, the image above. This is the same page, rendered by the same browser, on the iPad and iPhone 4. Note how the button looks smaller on the iPhone. This is because the iPad has a pixel density of 132ppi, while the iPhone 4, with its Retina Display, has a ppi of 326. The iPhone 4, however, automatically scales pages 2×, so we are effectively working with a ppi of 163. This is still about 15% denser than the iPad display, which means the physical display of the button button is about 15% smaller.
This pixel density must be taken into account when designing cross-platform mobile applications, for two primary reasons:

If you design a button for a 132ppi (like the iPad), it will come out much smaller for higher ppis, which could result in it becoming harder to tap and possibly render it unusable.

Images and UI elements must be scaled intelligently, to avoid pixellation and blurriness.

The General Concept

The overriding concept behind this technique is to use ems — a typographically relative measurement unit — to size your elements. Wikipedia describes an Em as such:

This unit defines the proportion of the letter width and height with respect to the point size of the current font… This unit is not defined in terms of any specific typeface, and thus is the same for all fonts at a given point size. So, 1 em in a 16 point typeface is 16 points.

Because font-size is an inherited property in CSS, we are able to change the scale of any em-based elements by simply changing the parent’s font-size.

Starting Simple: A Button

To put this concept into practice, let’s take a look at a simple button.

As you can see, we’ve added rounded corners, an inner glow (using inset with -webkit-box-shadow), a drop shadow, text shadow, and padding to our element — all using em as our sizing unit. The only sizing which is not accomplished with ems is the background-gradient, which must be defined in percentage-based color-stops. As these color-stops are still relative to the size of the button itself, these values are inherently relative as well.
To show off some different sizes for our button, we can easily just add a few classes like:

Caveat: Changing only the text size

The only troublesome part of this method is that you will occasionally want to change the actual font-size of an element, without affecting its overall scale. For this, we can use a wrapper div/span inside of our element, like so:

Images and Masks

The technique can also be used on images. For traditional images, it’s as easy as setting either the width or the height (the other will be automatically applied to remain proportional) in ems or percentages. We must embed a higher resolution photo, to be scaled down to meet the different sizes (we want to make sure we’re scaling down, as scaling up will result in pixellation).

The benefit of this technique is that your images will be the same physical size across different devices, but will have more resolution on the devices that support it.
It should be noted, though, that these images are not truly “resolution independent.” The very concept of resolution independence is impossible to apply to bitmap-based graphics. As mentioned, we created our image at a large size, anticipating that it would be scaled down. If the image were to be scaled up instead, it would become pixellated. The other unfortunate side-effect is wasted bandwidth — by always including a larger version of your image, you’re ensuring unnecessary kilobytes are being transferred.
Preview this step in a WebKit-based browser.

SVG to the Rescue

SVG is a W3C specification for vector images which is already implemented in WebKit (though not all versions*). Because SVG is vector-based, it can be infinitely scaled without detriment to quality. This is the best option available for icons, logos, and non-bitmap UI elements.

Community Sample: Loading Indicator

Jordan Dobson has implemented this technique to great effect by creating a CSS3-based loading spinner. Check out his demo page, which has buttons to make the spinner bigger and smaller (again, by changing the parent’s font-size).

Changing Size Per Devices

Once you have your entire UI and layout measured in ems and percentages, you can apply the font-size to the body to adjust the overall scale (previously, we were setting the font-size on a parent element of our target). Currently, in Sencha Touch, we use Javascript user-agent sniffing to detect the device, and then add corresponding classes to the body. Once those are added, we adjust the UI resolution like so:

The future: @media queries

Ideally, we should be able to detect and change style using CSS3 media queries. There is a specific addition to the CSS3 recommendation that would help here, though it has yet to be implemented on iOS or Android — the resolution attribute:

There is one media query attribute of note which iOS recently added, called device-pixel-ratio. As mentioned at the start of this article, the iPhone 4 (with Retina Display) automatically scales pixels 2× on web pages. Developers can check for the Retina Display with a query like this:

Conclusion

As device displays become denser and denser (did someone say Retina Display iPad?), finding the right method for creating resolution independent UI elements will become more and more important. Using ems and percentages is one such method, that we currently think is the strongest, but I’m curious: Do you know of others? Is there a change to the CSS3 spec that you think would improve this process?

Written by David Kaneda
David Kaneda leads the Sencha design team. As a designer, developer, and general web enthusiast, David enjoys writing about CSS and is responsible for the look and feel of our websites and software. Follow David on Twitter

David Kaneda

Ralph Haygood

There are still an awful lot of px’s in the Sencha Touch CSS, though. Just yesterday, I was working through the .x-tabbar.x-docked-top rules, because I needed smaller than standard tabs for a certain tab panel, and they’re full of px’s. That’s presumably because they’re a lot about background image management. Do you really plan to make the Sencha Touch CSS px-free?

Ralph Haygood

P.S.: I realize the lack of support for SVG in the Android browser is a problem. So I should have asked, do you really plan to make the Sencha Touch CSS px-free, assuming the Android browser eventually supports SVG?

Auré

Siki?

David Kaneda

* I do use the occasional px measurement in Sencha Touch, but only for borders/highlights. These could/may become ems, but ultimately, it’s not the worst thing, as they’re all ‘1px’ and just trying to say “the smallest unit possible,” in a sense (ie. A 1px highlight at the top of a tab). Other places where you see px are likely just in the process of being refactored.
* Using ems and SVG are somewhat different, so the fact that Sencha Touch will not _rely_ on SVG in the near future doesn’t affect that we’ll continue using ems for sizing.

Hope that helps answer your questions-

Ralph Haygood

David, thanks. I agree 1px borders, highlights, and shadows are little or no problem. As for SVG, I had in mind it can be used to make background images such as Sencha Touch’s tab image resolution-independent, as at

David Kaneda

Thanks Garrett — all good feedback. As web buffs (née standards buffs) we could argue all day about semantics, but ultimately, that doesn’t sound like a fun afternoon. The classnames are terrible of course, but were used purely for clarity in the demos. I definitely don’t recommend using names like that in production. As for the UA sniffing, I mentioned it’s not the best method, but until we have support for resolution in @media queries (or the ability to detect ppi via Javascript) I still think it’s the best can do right now. Thanks again-

John "Z-Bo" Zabroski

“The classnames are terrible of course, but were used purely for clarity in the demos. I definitely don’t recommend using names like that in production.”

A few years ago somebody wrote a great research paper, Design Fragments Make Using Frameworks Easier, that studied 36 code samples found on the Internet, used in open source projects, and showed they all were traceable back to code samples on Sun’s developer website, and that some of the demo code contained sub-par coding practices. The number of users affected by these sub-par coding practices cannot even be counted.

Bottom line: You should always provide code with your name on it that you would drop-in to production. Hope this comment changes your practices going forward, and that you will always post production-ready samples.

Robert Green

I agree with Garrett, using proportional measures is good advice but messing with the device resolution at the web UI design level is a bad idea. There are already a huge variety of screen resolutions being used just in desktop devices, why the sudden focus on mobile devices just because iPhone changed their dot pitch and provided a method to detect it?

Web developers need to concentrate on clear and effective communication. By all means present attractive pages that are viewable and useable for a wide variety of host environments but let users deal with device related issues such as different sized screens, number of pixels, aspect rations, dot densities and so on themselves.

For example, my eyesight isn’t what it used to be so zooming is very important when using Mobile Safari. Therefore it is extremely annoying when a site is configured to prevent zooming. A designer can’t know every visitor’s circumstance and can’t accommodate them all specifically, so instead they should try to allow as much freedom as possible when the site is viewed. Taking control of resolutions, orientation, font sizes, whatever is obstructive and thoughtless. Just don’t do it.