Mathias Bynens

Everything you always wanted to know about touch icons

· tagged with HTML, iOS, performance

“Touch icons” are the favicons of mobile devices and tablets. Adding them to your web page is easy, and I’m sure you already know how this works using HTML:

<!-- In its simplest form: -->
<link rel="apple-touch-icon" href="apple-touch-icon.png">

(It’s a shame Apple didn’t just implement the standard <link rel=icon> and chose to come up with a more verbose proprietary link relation instead.)

Apple iOS has supported touch icons since iOS 1.1.3. What’s weird is that Android 2.1+ also has apple-touch-icon support (with a few quirks).

For web pages that don’t specify a custom touch icon, a thumbnail screenshot of the page is used instead. Android has a default icon, and some systems fall back to the favicon if it’s available.

Fancy effects

iOS automatically adds some visual effects to your icon so that it coordinates with the built-in icons on the Home screen (as it does with application icons). Specifically, iOS adds:

As of iOS 2.0, you can prevent the addition of these effects by using the precomposed keyword:

<link rel="apple-touch-icon-precomposed" href="apple-touch-icon-precomposed.png">

Since the rel attribute accepts a space-separated list of values in HTML, theoretically it should be possible to fall back to the regular icon with added effects for iOS 1 without requiring an extra <link> element:

<link rel="apple-touch-icon-precomposed apple-touch-icon" href="apple-touch-icon-precomposed.png">

In practice, however, it doesn’t work that way. iOS 4.2 seems to ignore the entire declaration if you’re using the space-separated value technique.

I’d recommend to always use precomposed icons. It gives you full control over your icon, and it’s the only kind of icon Android 2.1 supports.

Different icon sizes

The Web Clip Icons section in the iOS HIG states that for iPhone and iPod Touch, you should create the following icons:

For iPad, a 72 × 72 pixel icon can be used.

It’s perfectly possible to just create one high-resolution icon and use that for all devices. In fact, this is how Apple does it. Devices with smaller screens or lower display resolutions will automatically resize the icon. The downside is that these devices will load the large high-quality image, while a much smaller file would have worked just as well. This wastes bandwidth and affects performance negatively for the end user.

Luckily, as of iOS 4.2 it’s possible to specify multiple icons for different device resolutions by using the sizes attribute:

<!-- For non-Retina iPhone, iPod Touch, and Android 2.1+ devices: -->
<link rel="apple-touch-icon-precomposed" href="apple-touch-icon-precomposed.png">
<!-- For first-generation iPad: -->
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="apple-touch-icon-72x72-precomposed.png">
<!-- For iPhone 4 with high-resolution Retina display: -->
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="apple-touch-icon-114x114-precomposed.png">

A few simple rules apply here:

But it gets more complicated. Pre-4.2 versions of iOS simply ignore the sizes attribute, so the above code snippet would be interpreted as:

<link rel="apple-touch-icon-precomposed" href="apple-touch-icon-precomposed.png">
<link rel="apple-touch-icon-precomposed" href="apple-touch-icon-72x72-precomposed.png">
<link rel="apple-touch-icon-precomposed" href="apple-touch-icon-114x114-precomposed.png">

Needless to say, only the last value in the document will be used on those systems. In this case, that’s the largest icon. Depending on how you look at it, it might be better to reverse the order of icons:

<!-- For iPhone 4 with high-resolution Retina display: -->
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="apple-touch-icon-114x114-precomposed.png">
<!-- For first-generation iPad: -->
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="apple-touch-icon-72x72-precomposed.png">
<!-- For non-Retina iPhone, iPod Touch, and Android 2.1+ devices: -->
<link rel="apple-touch-icon-precomposed" href="apple-touch-icon-precomposed.png">

This way, older iOS versions download the smallest icon instead of the largest one. So, instead of forcing the largest icon to all devices unless they support the sizes attribute (iOS 4.2+), we now serve the smallest icon unless @sizes is supported. In other words, we’re now using progressive enhancement instead of graceful degradation :)

When in doubt, always use this snippet. With support for nearly all iOS versions and devices, and as many different Android versions as possible, it’s the most robust way to add touch icons to your site.

I’ve had several people test this on a Nexus One running Android 2.3 (Gingerbread), and it seems @sizes is not supported there either. However, it behaves differently than old iOS versions: instead of using the last <link> element’s @href value, it will use that of the first <link> element with rel="apple-touch-icon" or rel="apple-touch-icon-precomposed". In the case of the above code snippet, that’s the largest icon available.

Look ma, no HTML!

If no icons are specified in the HTML, the website root directory will be searched for icons with the apple-touch-icon or apple-touch-icon-precomposed prefix. For example, if the appropriate icon size for the device is 57 × 57 pixels, iOS searches for filenames in the following order:

  1. apple-touch-icon-57x57-precomposed.png
  2. apple-touch-icon-57x57.png
  3. apple-touch-icon-precomposed.png
  4. apple-touch-icon.png

That’s right — for iOS, it’s not necessary to use HTML to add touch icons to your site, even if you want to use multiple resolution-specific icons. Say adiós to the boatload of proprietary <link rel="apple-touch-icon"> elements on every single HTML page. Just create different versions of the icon, use the correct file names and place them in the root. (favicon.ico, anyone?)

So, what do we need?

It’s a good idea to include both apple-touch-icon.png and apple-touch-icon-precomposed.png for maximum compatibility: iOS 1 and BlackBerry OS6 don’t support precomposed icons. (Note that Android 2.1 only supports precomposed icons.) You could use rewrite rules to avoid having to duplicate the file.

In total you should have five separate files.

Sadly, the no-HTML approach doesn’t work on Android yet (tested in 2.3 Gingerbread), although I’m sure it will be supported in a future version. I haven’t been able to test Android 3 (Honeycomb) or BlackBerry OS6 yet. If you want, you can test this technique on my website. Save a bookmark to this page to your home screen, and see if you get a custom touch icon or not. Please let me know what you find out!

Summary

So, which technique to use? It all depends, really.

Comments

Mathias wrote on :

I should probably add that I researched the use of media queries to serve different touch icons based on the device’s screen resolution. The code looks like this:

<link rel="apple-touch-icon-precomposed" media="screen and (resolution: 163dpi)" href="apple-touch-icon-57x57-precomposed.png">
<link rel="apple-touch-icon-precomposed" media="screen and (resolution: 132dpi)" href="apple-touch-icon-72x72-precomposed.png">
<link rel="apple-touch-icon-precomposed" media="screen and (resolution: 326dpi)" href="apple-touch-icon-114x114-precomposed.png">

Based on my tests, this doesn’t work correctly. The iOS devices I tested on — iPad, iPhone 3G S and iPhone 4 — were all running iOS 4.2, and they all just used the first touch icon referenced in the HTML. The media queries didn’t seem to matter; the order of <link> elements in the source did. Really weird.

Update: Looks like this has finally been fixed in iOS 5. It also works for startup images now:

<!-- 320x460 for iPhone 3GS -->
<link rel="apple-touch-startup-image" media="(max-device-width: 480px) and not (-webkit-min-device-pixel-ratio: 2)" href="startup-iphone.png">
<!-- 640x920 for retina display -->
<link rel="apple-touch-startup-image" media="(max-device-width: 480px) and (-webkit-min-device-pixel-ratio: 2)" href="startup-iphone4.png">
<!-- iPad Portrait 768x1004 -->
<link rel="apple-touch-startup-image" media="(min-device-width: 768px) and (orientation: portrait)" href="startup-iPad-portrait.png">
<!-- iPad Landscape 1024x748 -->
<link rel="apple-touch-startup-image" media="(min-device-width: 768px) and (orientation: landscape)" href="startup-iPad-landscape.png">

Björn wrote on :

Thanks for the great article. In my project I have been using JavaScript and user agent detection (ugh!), to build the link rel="apple-touch-icon" dynamically.

I will rip it out and replace it with this.

Ric wrote on :

Looks like a bit of a messy system to me, I guess scanning the root is okay. But if we add these link tags, the IE9 meta tags etc etc we'll soon have a 1000 line head block!

Kroc Camen wrote on :

Using rel="apple-touch-icon apple-touch-icon-precomposed" (or vice-versa) does not work in iOS 4.2 (and likely before), it ignores the whole declaration, so you must put composed and precomposed on separate LINKs.

David wrote on :

Great article. One thing I’m trying to find is if it’s possible to change the URL associated with the icon? For instance, if an icon is added from my homepage can I control what page the icon opens?

Steve wrote on :

I got nothing on my Nexus S running 2.3.4... But I'm not sure I set the link up right. I might have another play later.

Anselm H. wrote on :

Hi, what about behavior of devices if these icons are in root directory (and don't need to be linked)? Is it the same? Or do they choose the right then?

Thanks a lot for answering… -A.

Mathias wrote on :

Zev: apple-touch-icon never was a registered rel value; it was never really valid. The only thing that changed is the validator, which now explicitly marks invalid link relations as validation errors.

The same goes for shortcut; however, that one quickly was registered after the recent validator.nu update.

Anyhow, I think we can all agree that it sucks having to use invalid markup just to get touch icons to work on most devices. I’ll repeat what I wrote in the article:

(It’s a shame Apple didn’t just implement the standard <link rel=icon> and chose to come up with a more verbose proprietary link relation instead.)

Zev Goldberg wrote on :

Arrgh. I see that now.

Of course, I'm not even an Apple person, and I don't wish them to write the spec with their non-semantic name all over it. But I am a firm believer in the spec being written to follow the cowpaths. If they (and also Android) have the browsers to support it, shouldn't we push to have apple-touch-icon registered as well?

Mathias wrote on :

Zev:

If they (and also Android) have the browsers to support it, shouldn't we push to have apple-touch-icon registered as well?

It seems weird to standardize anything that has a vendor name in it (at least to me). But then again, shortcut got registered as well, so why not.

I’ve registered rel=apple-touch-icon now.

Henri Sivonen wrote on :

Mathias:

Why only apple-touch-icon why not apple-touch-icon-precomposed, too? I don’t have an iOS device here, so I can’t tell if it actually works as a rel value or if it only works as a magic file name. Apple’s docs kinda suggest it works as both. (Why did they make file names magic anyway?)

Mathias wrote on :

Henri: In my excitement I had simply forgotten to register apple-touch-icon-precomposed as well. Fixed now. Thanks for the reminder!

George wrote on :

I started seeing queries in my server logs for these PNG files even though I don’t have them on my system, nor do I have any links to them in any of my HTML files. LOL. So I added a soft link for apple-touch-icon.png to some 50 MB file on my system. Anythying that does a GET on a web server without first finding that filename in a parent HTML file deserves whatever it gets.

Ajay wrote on :

Is there any way to define custom text for the Home Screen icon? At the moment, it uses the page title and truncates it. My page title has a bit of descriptive text in it too for SEO purposes, but i'd like that to be removed for the Home icon.

I cant find any answers that say this is possible.. yet..

Luke wrote on :

Hi, great post. Is it possible to have a different web page title for Add to Home Screen, so it’s shorter? Without using some JavaScript to check. Thanks.

On browsers I’d like the proper webpage title, and a shorter version if they add to home screen on iOS device.

Brian French wrote on :

I tested your no-HTML approach in Android 3.2.1: Home screen bookmark to this page is a custom touch icon.

David Calhoun wrote on :

Just a heads up — it looks like touch icons in a password-protected directory aren’t accessible (tested on iOS5). This make sense, as the icons are requested by the system, not the browser (where a user may have typed in a user/pass).

Kristen Grote wrote on :

Hey Mathias,

Great writeup! Just thought I should let you know that I saved this page on my HTC Thunderbolt running Android 2.2.1 and I only got Android’s default bookmark icon.

Before reading this article, I was messing around on another site of mine, and I placed my apple-touch-icon.png file at the root, and removed the link to it from the site’s <head>. This caused the site icon to appear inside Android’s default bookmark icon. Whether it was the favicon or the apple-touch-icon being used, I don’t know. I’ll do some further testing if I have time and let you know.

Harri Hälikkä wrote on :

Ah, what a great mess this relatively simple thing is. Thanks for the excellent writeup!

One additional note: the default browser of the recently announced MeeGo-based Nokia N9 (and N950) device is able to add sites to application grid as well, but doesn’t support the -precomposed version. So, apple-touch-icon.png is needed to make the site play nicely together with this device. the icon can be just placed to the root of the site, no need to add a link to it in the <head>.

And to confirm, yes, this current page works well with N9, the icon is shown as it should be.

Apparently even sites such as m.twitter.com or touch.linkedin.com can’t get this right — it’s a bit frustrating.

Mike Cowles wrote on :

Hey,

I'm running into a brick wall with this.

I have a HTC EVO and put an icon at http://mikecowles.com/apple-touch-icon-precomposed.png in the root and in the folder of the mobile version I’m working on at http://mikecowles.com/mobile/apple-touch-icon-precomposed.png. I made it the lazy 114px size and have tried bookmarking the site and always get the default red ribbon with the star, icon.

Can you offer any help?

Thanks very much! =]
Mike. <><

betovarg wrote on :

By far, the best touch icon tutorial I've found. Saved my life with the reverse order, thats a must tweet tip.

thanx!

Kevin wrote on :

George: That’s an awesome idea. If my personal site kept on getting those requests I’d totally do it too. Sadly I don’t think it would go over well if I did that on a customer’s site.

Red Feet wrote on :

Ajay: Yes, a shorter title, different from your descriptive/long SEO title is possible:

<title>Long SEO title</title>
<script>
document.title = 'Short display title';
</script>

Luke: No, without JavaScript it’s not possible, but how many iOS users disable JavaScript?

Dries wrote on :

Mike: I’m having the same issue on my website when testing with my HTC Sensation. The fact that it works for Mathias makes me think that HTC Sense ignores apple-touch_icon.png while stock Android does recognize it.

iDGS wrote on :

Red Feet: Oo! Thank you! That’s exactly what I was looking for! Namely, a way to control the name given to the Apple Touch Icon that gets saved to the iOS desktop, while keeping my longer, carefully crafted title for SEO! Yes, I still wish I could set the ATI name directly, and thus keep and show my homepage title of choice. However, in the meantime, this is a compromise I can live with.

@Mathias: Maybe put a mention of this title-trickery gem up in the main text? I confess I was about to skip the comments and continue searching elsewhere. Glad I kept reading!

Sascha Hendel wrote on :

A note about transparency: if you use PNG images with alpha channel (transparency) iOS will make them opaque and use a black background instead. This happens even if you use the precomposed option!

Android supports (as far as I tested) transparency on precomposed icons (maybe on normal icons, too). You can create really nice icons with transparency on Android, because the OS does not insist on this boring rounded edge button style.

Right now I’m trying to set up a line of <link> tags with different parameters, to provide iOS with an opaque version (because I don’t want black background) and a transparent version for Android…

Sonya: A note about changing the page title with JavaScript — be careful with manipulating the page title this way. Google and other search engines could interpret this as bad SEO.

James wrote on :

No matter what I've tried I cannot get these icons to show on my HTC Sensation. I always get the red ribbon bookmark icon. Has anyone been able to get past this on this phone?

iDGS wrote on :

Sonya: Ooo! Lovely script refinement! And that Unicode-escape demo is a nice touch. Many thanks! (For a few additional usage notes, see comments "over yonder." )

Leave a comment

Comment on “Everything you always wanted to know about touch icons”

Some Markdown is allowed; HTML isn’t. Keyboard shortcuts are available.

It’s possible to add emphasis to text:

_Emphasize_ some terms. Perhaps you’d rather use **strong emphasis** instead?

Select some text and press + I on Mac or Ctrl + I on Windows to make it italic. For bold text, use + B or Ctrl + B.

To create links:

Here’s an inline link to [Google](http://www.google.com/).

If the link itself is not descriptive enough to tell users where they’re going, you might want to create a link with a title attribute, which will show up on hover:

Here’s a [poorly-named link](http://www.google.com/ "Google").

Use backticks (`) to create an inline <code> span:

In HTML, the `p` element represents a paragraph.

Select some inline text and press + K on Mac or Ctrl + K on Windows to make it a <code> span.

Indent four spaces to create an escaped <pre><code> block:

    printf("goodbye world!"); /* his suicide note
was in C */

Alternatively, you could use triple backtick syntax:

```
printf("goodbye world!"); /* his suicide note
was in C */
```

Select a block of text (more than one line) and press + K on Mac or Ctrl + K on Windows to make it a preformatted <code> block.

Quoting text can be done as follows:

> Lorem iPad dolor sit amet, consectetur Apple adipisicing elit,
> sed do eiusmod incididunt ut labore et dolore magna aliqua Shenzhen.
> Ut enim ad minim veniam, quis nostrud no multi-tasking ullamco laboris
> nisi ut aliquip iPad ex ea commodo consequat.

Select a block of text and press + E on Mac or Ctrl + E on Windows to make it a <blockquote>.