Creating and using custom icons in jQuery Mobile
Filed under: jQuery Mobile
comments (81) Views: 85,967
So you've read Introduction to jQuery Mobile and you've built your first application. You're happy with it, but you want some different icons. The icon set that comes with jQuery Mobile has some nice ones in it, but they're not enough for people who really want to spice up their application. This blog post will show you how to create and implement custom icons. In addition I'll show you how to add high res icon support for iPhone 4's Retina display and newer high resolution devices.
jQuery Mobile uses white PNG 8 bit icons sized at 18x18 pixels. They specify 8bit PNG files, but any image is acceptable. However, if you decide to mix and match packaged icons with custom icons, it's best to stick with white icons for consistency. If you decide to replace all icons, then use GIF or PNG, anything that will give you transparency.
Fire up Photoshop, or the image editing app of your choice, and create a new file at 18x18.
Draw your own icon or find an existing icon from any number of icon sites. Preference should be given to using a vector file for your icon as we'll be increasing the size in a few moments. When you're ready to save your icon select File > Save for Web & Devices and make your settings look like those in the image to the right. Call the image settings.png.
After you've exported your image at 18x18, you'll want to size the canvas upwards, to 36x36 pixels. Select Image > Image Size (or Alt + Ctrl + I). Touch up your icon accordingly, then save for web as before, but this time name the file settings@2x.png. The name of the high-res file doesn't mean anything to jQuery Mobile, but in iPhone development, the @2x indicates a file that is exactly twice the pixel dimensions of a file without the @2x.
If you recall, jQuery recommends hot-linking to the JavaScript and CSS files used by jQuery Mobile as hosted by jQuery themselves. That means we can't alter those files. So once you've got your images saved, we'll need to create a new CSS file that will contain our custom changes. Call it whatever you like, save it wherever you like, but it'll remain empty for a few minutes.
For simplicity's sake, we're going to create a simple button that will use our icon. The code for that button will look like this
- data-role = tells the standard link to behave, and look, like a button.
- data-theme = tells the button which jQuery theme to implement.
- data-iconpos = tells the icon where to appear. Default is left; options are right, top, bottom, or notext (which results in a round button with the selected icon at the center) .
- data-icon = selects the icon. To use built in jQuery icons, simply use a single word like home, add, forward, back, etc. To implement a custom icon use a string such as "twitter-bird" or "myapp-settings". jQuery Mobile will generate a CSS class declaration of ui-icon-myapp-settings that we'll be using to hook into.
Open up the custom CSS file that you created moments ago, and add this class declaration
Save all your files and view the project in your browser. At this point your button should now be displaying your custom icon, congratulations! If it's not, a few things to check...
- Is the file in the right place, or being linked to correctly?
- Did you upload, and correctly link to, the custom CSS file. Remember that the custom file needs to appear after the standard jQuery Mobile file in your code.
- If it's still not showing up, clear your cache. jQuery Mobile hangs on to your files like a miser holds on to his last dime.
Now that your icon is in place let's add in the code needed to implement a high-res icon. jQuery Mobile uses something called CSS3 media queries to detect whether your device is capable of the goodness. We can also use a media query to see if your device is capable of pixel doubling. It looks like this
Broken down that says any screen device capable of double pixel density gets the stuff inside. So now let's take a look at our custiom CSS delcaration now.
Notice that the only differences in this declaration are the different filename, and we're adding a background-size attribute. This forces the 36x36 icon to be sized to the 18x18 size we need.
Hope this article helped you out, and encourages you to try out jQuery Mobile; currently in it's Alpha 3 release. Hit up the demo link to see this code in place. Click the button labeled Custom Icons. If you don't have an iPhone 4 to test with, bug your Apple nerd friend to look at your project once you're done.
If this article was interesting, or helpful, or even wrong, please consider leaving a comment, or buying something from my wishlist. It's appreciated!
Thanks!
John Gag - April 05, 2011 06:11 pm
My pleasure John. Hope it helped you out. Don't forget to post a link to your app when it's done so that others can check it out.
andy matthews - April 07, 2011 09:28 pm
Andy, It appears the images stay in some sort of circular viewport. I want to create a square image...is this possible? If not, do you know of another method I can use? Thanks! -jp
JP - April 09, 2011 06:31 pm
JP...I believe it's because the icon container has a border-radius applied to it. That can be removed, or adjusted, by overring the style of that container with a custom CSS file. Peep the container with Firebug for Firefox, or Chrome's Developer Tools inspector.
andy matthews - April 12, 2011 02:14 pm
Is there any way to use background-position with background-size? I usually put all the graphics in a single file for mobile sites to reduce HTTP-requests. But I get an empty picture if both position and size are applied.
Oiva - April 14, 2011 06:06 am
Oiva...you sure can. In fact, if you're placing single images as backgrounds for high-res display that's how you have you to it.
andy matthews - April 17, 2011 12:57 pm
thank you
seunghuny - April 28, 2011 08:38 pm
Thanks for the help! I was able to, with your help, figure out the round viewport thing. I wanted to plop a Facebook icon on a jQuery Mobile button using this technique, but it looked pretty bad rounded off. I used Firebug on my desktop machine to inspect the button and found it is the .ui-btn-corner-all class that is calling the border-radius of 1em. That is what makes the nice rounded buttons. So, I created the separate class, using the icon designator on my button, and put it on the page AFTER the jQuery CDN calls, as follows: .ui-icon-fblogo{border-radius:0px; background: url("image/facebooktiny.png") no-repeat rgba(0, 0, 0, 0.4) !important;} .ui-btn-corner-all .ui-icon-fblogo{border-radius:0px;} (Of course, wrap this in style tags) My button code looks like this: Follow Us on Facebook I hope that helps someone further!
Mark Brodsky - July 13, 2011 12:43 pm
Mark, you could also do it using the built in icon framework. Take a look at this signin page for my company's mobile website. Note the Facebook signin button at the bottom:
http://andym.goba.mobi/#signin.html
andy matthews - July 17, 2011 08:23 am
Excellent article thanks. One question though, I would really like to use a larger sized icon than 18x18 - is this possible or will it confuse JQuery mobile? Against recommendation I am currently intending to store all my JQuery .js and .css files locally so I could adapt their css if necessary and I also have created a custom css file of my own. Any suggestions? Many thanks
Simon Powers - July 28, 2011 03:04 am
I think you could probably use a larger sized icon than 18x18 but you'd have to modify significant portions of the CSS to allow for it. Bigger icon means larger space around the icon which would also mean larger buttons to account for the larger space, and so on. Then, when it was time to upgrade to the next version of jQuery Mobile you'd be in trouble.
andy matthews - July 28, 2011 08:35 pm
Rocking great overview and excellent explanation. Thank you. One brand new thing with jQM, they have a custom media query. Read about it here: http://jquerymobile.com/test/#/test/docs/api/mediahelpers.html Details here: Running Media Queries jQuery Mobile provides a function that allows you to test whether a particular CSS Media Query applies. Simple call $.mobile.media() and pass a media type or query. If the browser supports that type or query, and it currently applies, the function will return true. If not, it'll return false. //test for screen media type $.mobile.media("screen"); //test a min-width media query $.mobile.media("screen and (min-width: 480px)"); //test for iOS retina display $.mobile.media("screen and (-webkit-min-device-pixel-ratio: 2)");
Brent - August 21, 2011 11:25 am
Andy, I have a requirement for which I have been googling for last two days but could find any solution.... Problem is --- I have to add a Icon or a Button to which if the user clicks then that web apppication will get downloaded to his mobile phone and rather opening his browser every time , he will just click on that applicaiton to open that application. Please suggest me how to achieve this.... Best Regards, Nitin
Nitin - September 07, 2011 04:08 am
Nitin, sorry for not getting back to you sooner. It's not possible to download a website to your mobile phone. However, for some mobile phones you can add an icon for your website to their home screen. Then when the user clicks that icon, the website launches in full screen mode acting like an app. Take a look at this URL: http://stackoverflow.com/questions/6162070/jquery-mobile-add-the-home-screen-options
andy matthews - September 15, 2011 08:10 am
i have put code like Custom Icon and css is .ui-icon-myapp-settings { background: url("settings.png") no-repeat rgba(0, 0, 0, 0.4) !important; } still it shows a + icon and not my icon , css directory -- ../css/style.css image directory ../css/images/settings.png and i get a view like (check link) http://img7.imagebanana.com/img/jw2s2jzy/Selection_001.png ..
Sahil - October 19, 2011 04:06 am
Sahil... I think you might have discovered a bug in this blog post. Please change 'data-icon="myapp-custom"' to 'data-icon="myapp-settings"' and try again. If you post back that it works I'll update my post and give you credit for catching the mistake.
andy matthews - October 19, 2011 08:33 pm
Sahil's right the icon will be a + with the code here, Andy your comment of changing it to 'data-icon="myapp-settings"' fixes it. :)
Rowan - November 15, 2011 03:35 am
Update: Sahil caught a bug in the first code block data-icon="myapp-custom" has been changed to data-icon="myapp-settings". Thanks for the catch Sahil.
andy matthews - November 15, 2011 05:41 am
Thanks for the tutorial, Andy. I got my custom icon to work right the first time, and that'sunusual for me, a non-programmer. I'm subscribing to your blog.
Liz - November 18, 2011 10:40 am
Thanks a lot, Andy. Your tutorial allowed me to quicky have a custom icon on my first jQuery Mobile project in less than 5 minutes. Great!
Stteve - December 04, 2011 06:10 pm
My pleasure Steve...glad to help. Keep an eye out for the jQuery Mobile book being published by Packt Press in spring 2012. I'm contributing several chapters.
andy matthews - December 04, 2011 06:53 pm
I can't make the custom icon work. I had to put the style statements in the button declaration itself, but my image still looks faint. I can't tell if it's my image or my jQuery. You can see what I've done at clanramsay.org/testing/stpaul_mobile.html and my image is in clanramsay.org/images/facebook_icon.png. I've tried many combinations of code and image changes. Mostly I got dark blue buttons. My current situation is an improvement, but it is faint.
Alice - December 04, 2011 07:28 pm
Alice... I noticed that you've got an opacity of .5 on the anchor tag containing the facebook icon. I also noticed that your opening anchor tag isn't closed properly on the same icon. Fix those two things and I'll wager that your issue will be resolved.
andy matthews - December 04, 2011 09:21 pm
It's gotten worse. I fixed the closing of the anchor (thanks!), but that wasn't the opacity, it was the position. I did add an rgba selection just like yours, which includes opacity. But now I also have the plus sign icon on top of my very faint icon and I gave up on data theme b, because it was making all my list items blue, when they should be light grey. I don't understand what I'm doing wrong.
Alice - December 07, 2011 04:35 pm
Why I oughta... I decided to get down to the bottom of your problem Alice. I spent an hour reducing and comparing to the documentation. Until I realized that your custom CSS class, .ui-icon-myfacebook, is contained within a SCRIPT tag instead of inside a STYLE tag like it's supposed to be. On your current page on line 19, simply change the script tags to style tags and you're good to go.
andy matthews - December 07, 2011 08:56 pm
Thank you! I knew it had to be something simple -- it's been too long since I programmed on a regular basis. Now the icon looks great. For some reason I can't use data-theme="b" on all the sections anymore. The list items turn all blue (which isn't what theme b is supposed to do), but I just use it for the header and footer and it's fine. Thank you so much for your help and your patience with an old-time programmer.
Alice - December 08, 2011 02:59 pm
Follow-up to the issue of using larger icons: There is a now demo on the jQuery Mobile website that uses larger icons http://www.stokkers.mobi/valuables/bartender.html
Michael Ritchie - January 20, 2012 12:11 pm
Thanks for posting this Michael.
andy matthews - January 21, 2012 07:28 am
hi i have a problem i trust that us can help me .. the thing is that i use another .css for my page and when i change to another page the other page have the same style and the javascript in the page dont work !! please help me
Mariana - January 25, 2012 12:11 pm
good
karl - January 26, 2012 01:39 pm
Thanks for this Andy! Is there a way to add a rollover/hover state to a custom icon?
DWL - February 09, 2012 09:50 am
DWL...that's sort of a misleading question. Icons can only be applied to buttons or nav elements, both of which already have rollover states built into jQuery Mobile. Do you have a specific idea that I could help you with?
andy matthews - February 10, 2012 05:38 am
I'd just like to modify the default arrow icons on buttons on my website to show as maroon - same as the footer. A simple way to do that in the css file?
SFH - February 14, 2012 06:28 pm
SFH...nope. The arrows (and other icons) are actually images. To modify them you'd need to open the image file, colorize it, and save it out again. The default icons are saved as 8bit PNG files (similar to a GIF), but they don't have to be. They could just as easily be 24bit PNG files with alpha transparency.
andy matthews - February 14, 2012 07:33 pm
That's fine. But for some reason I cannot even locate the icons to do that. Where would they be? I checked all the directories for my site above.??
SFH - February 16, 2012 06:12 pm
>> DWL...that's sort of a misleading question. Icons can only be applied to buttons or nav elements, both of which already have rollover states built into jQuery Mobile. Do you have a specific idea that I could help you with? << Sorry if my question was off a bit. Here is my issue: I got a comp from a designer that used custom icons for a listview. Problem is, when you rollover/tap the listview button, the background/bar becomes the same color as the custom icon. JQM seems to do really well when the rollover state still has enough contrast to accommodate the custom icon. I managed to fix the problem with some jquery but it just seems like there might be an easier way out of the box that I am missing. Cheers!
DWL - February 16, 2012 06:37 pm
You mentioned that your footer is maroon which means you likely used ThemeRoller to create a custom theme (good for you!). When you download your ThemeRoller theme, the ZIP file includes an images directory which contains the icons. If you don't have the icons in that image folder then you probably deleted it without realizing what it contained. You can re-download the images from the jQuery Mobile site:
http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.zip
andy matthews - February 16, 2012 06:51 pm
DWL, do you have an example I could see online? I sort of understand what you mean, but a visual would be easier.
andy matthews - February 16, 2012 06:52 pm
Actually, I got the files from the jQ mobile development platform on an FTP server I used during a jQuery training program. All the files and folders are on my currently FTP server now and there is no directory with images. Don't believe there ever was. Here's website: http://libcat.biola.edu/screens/m/index.html
SFH - February 17, 2012 04:17 pm
SFH...if you use Firebug or Chrome Dev tools, right click on the right facing arrows in your website and select Inspect Element. You'll see that you're linking to the CSS file on jquery's CDN (which is perfectly acceptable). The only drawback is that you can't edit the images there. Just download the files directly from their site using the link I provided. Then you can recolor the images and use them directly in your project.
andy matthews - February 17, 2012 08:41 pm
Andy, Here is a screeny of a list view nav ( http://tinypic.com/r/70dnh4/5 ). The top bar is on the hover/tap state. When you rollover the buttons the custom icon needs to turn from blue to white. I solved this with jquery by finding the class jqm attaches to the button and adding a hover state class to it on hover/tap. I'm wondering if there is a better way to accomplish this without using jQuery to switch the class of the custom icon? Thanks so much for your time!
DWL - February 20, 2012 09:48 am
DWL... jQuery Mobile's icons are single color only. You're either using the default black, or the default white icons...or you're coloring your own. Regardless, if you want to change the icon color as part of an interaction you're going to have to write your own code.
andy matthews - February 20, 2012 08:57 pm
Thanks for all the replies, I appreciate the help.
DWL - February 23, 2012 05:35 pm
hi, i have some problem with my mobile web, when i test my mobile web in the browser in ipad, the icon seems to change size when i change the layout, how to fix the icon either it is vertically or horizontally?thanks
MO - February 23, 2012 07:54 pm
Can you post a link to your website? I don't have an iPad so I can't see it personally, but you could also take a screenshot on your iPad and post a link to that.
andy matthews - February 23, 2012 09:44 pm
He may be talking about the orientation bug in iOS. This javascript fixes it. https://github.com/scottjehl/iOS-Orientationchange-Fix
Brent - February 23, 2012 10:13 pm
Andy, I've tried multiple times with no success. Going through the process always results in my custom icon not showing, rather just the plus. You mentioned that the css file can be saved anywhere and named anything. My image location is /Content/images/custom-icon.png, my css file location is /Content/myIcons.css, the button code is Custom Icon, and the css code is .ui-icon-myapp-settings { background: url("images/custom-icon.png") no-repeat rgba(0, 0, 0, 0.4) !important; } Is there anything noticeable to you that I'm doing wrong? Your help is greatly appreciated.
Shawn - February 24, 2012 07:08 am
Shawn...you might have already fixed this, but your image file path in your CSS is wrong. When specifying an image in a CSS file the path to the image is always relative to the location of the CSS file. So in your case, your browser would most likely be looking for the image in the wrong directory.
Best way to determine what's actually happening is to use Firebug (in Firefox) or Developer Tools (in Chrome). Open the net tab that shows you http requests made by your browser and you'll probably see a 404 for the image. Change the location of the image, or the path in the CSS and you're golden.
If that's not it, then throw your code up online and I'll take a look at it.
andy matthews - February 24, 2012 06:34 pm
Thanks so much for this information I'm currently using custom icon pack provided by you it's really cool and i'm liking that.
Abhimanyu Sharma - March 10, 2012 12:55 am
Abhimanyu, thanks for your kind words. Hope you like the icon pack.
andy matthews - March 10, 2012 12:38 pm
This is awesome! I'm a web designer and I just created my first jQuery Mobile site and this tutorial helped me a ton. Thanks so much!
Jason - April 10, 2012 11:52 pm
Hi Andy, thanks for the great tutorial. I am facing with a weird thing. I followed all the steps and now when I am opening the html file offline by clicking on it it shows my custom icon but when I open it through the server using a url it doesn't show up! If it matters my server is written in node.js. What can be a problem here?
Thanks,
Salma
Salma - May 14, 2012 07:23 pm
Salma...
My guess is that your path is incorrect. If you inspect your page using Chrome's Developer Tools or Firefox's Firebug I bet you'll see a 404 page for the icons.
andy matthews - May 14, 2012 07:36 pm
I wish this was the problem and I could solve it right away, but no! there is no error!! Instead of showing the custom icon it shows the icon "plus"! What else can be wrong here!
Salma - May 15, 2012 02:50 pm
Then the next best thing would be for you to post your website here so that I can take a look at it.
andy matthews - May 15, 2012 07:05 pm
The web export image in article has gif settings when the file is going to be png.
"When you're ready to save your icon select File > Save for Web & Devices and make your settings look like those in the image to the right. "
Once I made the jump however (in Fireworks) it worked with PNG 8 as you were explaining in the article.
Lon Hosford - May 31, 2012 03:50 pm
Lon...I'm not sure how I missed that. Good call. I'll update the image accordingly.
andy matthews - June 01, 2012 05:48 am
Hey Andy,
Thanks for the great writeup. Helped me figure out how to include icons on the app I'm working on.
However, I've come across an interesting problem. I've setup my custom icons and when I run my app from Xcode, my custom icons show up. However when I install a build of my app on my iPhone, the icons do not show at all and nothing else shows in their place.
I've checked my code to ensure I did follow your examples, but I'm puzzled as to why it works fine in the iPhone Simulator but not on the device.
Anil Natha - June 11, 2012 02:37 pm
Anil...
What sort of pathing are you using? Are the icons relative to your CSS which is relative to your document?
andy matthews - June 12, 2012 06:34 am
Yes, the paths to the PNG's are relative to the CSS which is relative to the document it's being loaded into.
Anil Natha - June 12, 2012 08:56 am
Hey Andy, this is a great article! Thank you.
I've been gathering information about advanced customization of the jQuery Mobile Themes and I am happy to see that you addressed the media query to render the icon in highres.
Very cool!
-Raul
Raul - July 22, 2012 12:38 am
Thanks Raul! Appreciate your kind words!
andy matthews - July 23, 2012 10:45 pm
Hi, Im trying to do a button with a custom icon, I follow your example, but I have a question, How can I put the icon in the button but without leaving any space between the button
for example i have the button and inside of it the icon, but there is space at the end of image (icon)
thanks in advance, and sorry for my english
Conchitabh - July 24, 2012 10:44 am
Thank you, Andy! As a designer, I'm trying to do quite a bit of customization to get the look I want. This is great. You rock! :-)
-Sara
Sara Brown - August 16, 2012 12:41 pm
Thanks for the kid words Sara! Make sure to check out the "Going Deeper with jQuery Mobile" presentation I gave at jQuery Con this year. Loads of tips in there on how to improve the appearance of your app.
andy matthews - August 16, 2012 02:25 pm
Great.
Tks 4 share!
kiko - August 21, 2012 06:02 pm
budy your site ROKS! Thanks @pblfer
pblfer - September 01, 2012 12:30 am
Hi,
Thanks a lot for this article. And also thanks Mark for telling how to remove that rounded corner thing. This is very helpful for me because I am new to these things, I was working in Flash and Flex since 6 years and I have very little knowledge of html/css. Now as all know Flash/Flex projects are less in the market. So I am also learning HTML-5, jQuery mobile. Its jQuery mobile to start with.
-Varun
Varun - September 05, 2012 04:37 am
Pretty good post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog posts. Any way I'll be subscribing to your feed and I hope you post again soon.
Elaine - September 21, 2012 02:19 am
thanks..your work really helped me.
lucy - September 21, 2012 02:22 am
I hope you can accept my comments!!!!!
Elaine - September 21, 2012 05:49 pm
Why your website one can only send a comment!!!!!
Martin - September 21, 2012 06:00 pm
Thanks bro! it helped me spice up my app. God Bless!
Nicolas - October 06, 2012 07:32 pm
Works like a charm! Thank you very much!
Sander - October 11, 2012 02:56 am
Great job man!!!
alessandro - November 14, 2012 06:32 am
Thanks for your kind words everyone. Appreciate the sentiments.
andy matthews - November 19, 2012 08:31 am
I'm trying to do quite a bit of customization to get the look I want. This is great.
bowen - December 25, 2012 01:19 am
This blog was... how do I say it? Relevant!! Finally I have found something which helped me. Many thanks!
Natalya Rase - January 21, 2013 04:39 pm
is ther a video to show hot to install custom icons? cant seem to get it ryt. please help ASAP!!!
Victor - February 05, 2013 11:57 pm
Victor, I'm afraid there isn't. Could you tell me where you're having trouble? Do you have an example implementation that I could review?
andy matthews - February 06, 2013 05:42 am
Gracias, Andy, te saludo desde Costa Rica, amigo. Te agradezco todo tu trabajo y tu generosidad de compartir tus conomientos.
Thanks, Andy, you greetings from Costa Rica, friend. I appreciate all your work and your generosity in sharing your knowledge.
Erick Castro - March 21, 2013 11:13 pm