Creating and using custom icons in jQuery Mobile
Filed under: jQuery Mobile
comments (42)
Views: 34,710
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