jQuery Mobile Tutorial: Creating a Restaurant Picker Web App Page 2
Now that we have made it through the build portion of the jQuery Mobile tutorial, we have to make it shine with a little bit of style.
Custom CSS: Styling Our jQuery Mobile App
You will find all the files used to style this app in the .zip file. You are allowed to use them for demo purposes, but not for any commercial use. To style the jQuery Mobile app you have two solutions: you can either remove the jquery.mobile-1.0.1.CSS and create your own styling from scratch, or you can add a third CSS stylesheet that will replace some of the jQuery Mobile styling. Here we go with the second option, since most of the jQuery Mobile base design works for this app. You could also use the jQuery Mobile Theme roller if you want to create custom themes without having to write too many lines of CSS.
Some Global Styling
Here is the part of the CSS that changed some of the global jQuery Mobile styling.
/*** general styling */ .ui-page.ui-body-c{ background:url(images/bg.png); box-shadow: 0px 0px 30px 5px rgba(107, 105, 105, 0.3) inset, 0px 0px 0px 1px rgba(107, 105, 105, 0.4) inset; } .ui-icon.ui-icon-arrow-r { background-color:rgb(136, 111, 110); } .ui-corner-all, .ui-corner-top, .ui-corner-bottom, .ui-corner-tl, .ui-corner-tr, .ui-corner-bl, .ui-header .ui-btn-corner-all, .ui-listview-filter .ui-btn-corner-all, #restau_infos .ui-btn-corner-all, #contact_buttons .ui-btn-corner-all, #notation .ui-btn-corner-all{ border-radius:0.2em; } .ui-btn-active { background: #654644; /* Old browsers */ background: -moz-linear-gradient(top, #654644 0%, #331c1b 100%); /* FF3.6+ */ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#654644), color-stop(100%,#331c1b)); /* Chrome,Safari4+ */ background: -webkit-linear-gradient(top, #654644 0%,#331c1b 100%); /* Chrome10+,Safari5.1+ */ background: -o-linear-gradient(top, #654644 0%,#331c1b 100%); /* Opera 11.10+ */ background: -ms-linear-gradient(top, #654644 0%,#331c1b 100%); /* IE10+ */ background: linear-gradient(top, #654644 0%,#331c1b 100%); /* W3C */ color:#fff !important; } .ui-content .choice_list .ui-btn-active .ui-link-inherit, .ui-btn-down-c a.ui-link-inherit, #home .ui-btn-down-c a.ui-link-inherit{ color:#fff !important; } img{ max-width: 100%; height: auto; width: auto; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .ui-grid-a .ui-block-a, .ui-grid-a .ui-block-b { width: 48%; padding:1%; }
The first lines add the texturized background to the app, and the box shadow that will give the whole design some depth. We also changed the background color. Working with a lot of iOs apps, the rounded corners are a bit overused (but that’s personal tastes) so for the tutorial we changed all the jQuery Mobile heavy 0.6em rounded corners to some more discreet 0.2em radius corners. Then we change the active blue gradient, to a brown one.
The last trick here is a responsive image hack, to make them behave nicely on all kinds of browsers.
Styling the Landing Page
The first page of the app should have a very special style. It is where the user first lands, so it has to be catchy so they will stay. Now we need nice little logo to use as the branding of the app. Here is what we will create:
Let’s take a look at the CSS.
/*** home **/ #branding{ background:url(images/logo.png) no-repeat; width:322px; height:165px; text-indent:-999px; font-size:0px; margin:-10px auto 0 auto; border-bottom:1px solid rgba(65, 38, 37, 0.6); } .choice_list h1{ margin-top:30px; font-size:18px; color:rgb(65, 38, 37); font-weight:normal; font-style:italic; padding:5px 0 6px 50px; background:url(images/pagination.png) no-repeat; } #home .choice_list h1{ background-position: 0 -16px; } #home .choice_list h3{ padding-top:10px; color:rgb(63, 41, 39); } #home .choice_list .ui-btn-active a.ui-link-inherit h3{ color:#fff; } .choice_list img{ padding:3px; }
As you can see, we used a well known trick to make the text of the branding element disappear and display the logo instead. We also styled the h1 question using a nice sprite, and added some padding to the list elements so that they will be centered with the images.
Styling the Second Page
Here is how the second page will look.
And here is our CSS code.
/* title bar */ .ui-header.ui-bar-a{ background:url(images/header_bg.png); } .ui-header .ui-title { text-indent:-9999px; font-size:0px; background:url(images/header_logo.png) no-repeat 69% 5px ; height:33px; padding:5px 0 5px 50px; margin:0px; } .ui-header .ui-btn-up-a { background:rgba(255, 255, 255, 0.1); box-shadow:none; } .ui-header .ui-btn-hover-a { background:rgba(0, 0, 0, 0.3); box-shadow:none; }
Once again we used a text replacement trick to make the title bar text disappear and put in the branding. The background of this bar was also changed to a brown gradient, and so was the back button. Again we added the sprite to style the question, and the last #choisir_ville .ui-listview-filter is here to prevent the button that clears the filter to get the top padding.
Style the Third Page: Restaurant Choice
This is what our page will look like:
And here is our CSS.
/** choix du restaurant **/ #choisir_restau .choice_list h1{ background-position: 0 -132px; margin:10px auto 20px auto; } #choisir_restau .choice_list a{ padding-top:10px; color:rgb(63, 41, 39); } #choisir_restau .classement{ display:inline-bloc; background:url(images/pagination.png) no-repeat 0 -182px; height:22px; text-indent:-999px; font-size:0px; } #choisir_restau .one{ width:30px; } #choisir_restau .two{ width:55px; } #choisir_restau .three{ width:75px; } #choisir_restau .four{ width:99px; }
The interesting part here is the trick used for the stars. We only used one image that contains the four stars as a background. The secret is to change the width of this element, so that only one, two or three stars will appear depending on our class. We also hide the text.
Styling the Last Page: Restaurant Details
This is the page that required most of the work, and here is how it will end up.
And here is our CSS code.
/** restau **/ #restau_infos, #contact_infos { color:rgb(63, 41, 39); font-size:14px; } #restau_infos h1, #contact_infos h2, #notation h2{ color:rgb(63, 41, 39); font-size:18px; margin:0 auto 5px auto; } #restau_infos p, #restau_infos ul, #contact_infos p{ margin:2px auto 5px auto; } #restau_infos ul{ padding:0 0 0 10px; } #restau_infos ul li{ list-style-type:square; margin-left:5px; } #restau_infos .ui-block-b .ui-btn { font-size:12px; } #restau_infos .ui-block-b .ui-btn-inner{ padding:5px; } #contact_buttons a{ color:rgb(63, 41, 39); } .ui-icon-maps { background: rgb(63, 41, 39) url(images/maps.png) no-repeat; } .ui-icon-tel{ background: rgb(63, 41, 39) url(images/phone.png) no-repeat; } /** add the stars to the drop down */ #note_utilisateur-menu a{ padding-left:100px; position:relative; } #note_utilisateur-button span.ui-btn-text{ background:url(images/pagination.png) no-repeat; } #note_utilisateur-button span.ui-btn-inner{ padding-left:5px; } #note_utilisateur-menu li a:before{ content: " "; display:inline-block; width:115px; height:20px; background:url(images/pagination.png) no-repeat; position:absolute; left:0px; } .one #note_utilisateur-button span.ui-btn-text, #note_utilisateur-menu li a:before{ background-position: -75px -182px; } .two #note_utilisateur-button span.ui-btn-text, #note_utilisateur-menu li + li a:before{ background-position: -52px -182px; } .three #note_utilisateur-button span.ui-btn-text, #note_utilisateur-menu li + li +li a:before{ background-position: -27px -182px; } .four #note_utilisateur-button span.ui-btn-text, #note_utilisateur-menu li + li +li +li a:before{ background-position: -2px -182px; }
The first lines are just basic styling to make it all look nice on the screen. What’s noteworthy is the .ui-icon-maps and .ui-icon-tel. Remember we gave the buttons a special data-icon name, and this created our classes. With those classes, we can easily add some custom icons to the button, just by changing the background image.
The last part, is the trick to add the stars to the select list. The stars are in the pagination.png sprite, but here, we won’t be able to use the width trick used on the previous page. Instead we will use a pseudo class with a fixed width, and “hide” the stars we don’t need by pushing the background position to the left. Since our items don’t have any special class, we will have to use the + selector, to target each li element, from first to fourth.
The last trick is to add the stars to the selected item of the list. Unfortunately, we will not be able to do this in pure CSS and will have to use a little JavaScript here (actually some jQuery). The main idea behind this script, on page load and on change, is to get the class of the selected element (remember that we gave them class in our HTML), and to apply this class to our select box so that we can dynamically change the stars.
Here is the script.
$( '#restau' ).live( 'pageinit',function(event){ var SelectedOptionClass = $('option:selected').attr('class'); $('div.ui-select').addClass(SelectedOptionClass); $('#note_utilisateur').live('change', function(){ $('div.ui-select').removeClass(SelectedOptionClass); SelectedOptionClass = $('option:selected').attr('class'); $('div.ui-select').addClass(SelectedOptionClass); });
$( ‘#restau’ ).live( ‘pageinit’,function(event){ is the jQuery Mobile equivalent to document.ready. We make two tests: one when the page is loaded, and the other when the change is triggered, meaning when we select another rating. This script adds the number of stars as a class to #note_utilisateur-button, and you can see in the CSS above that we used the same :before tricks to add the stars.
One Last Little Trick
The last thing we could do, to give this web-app a final touch, is to create a favicon for iOs devices. On iOs devices, users can create a shortcut for the app on the “desktop” so it is nice to create an icon for this shortcut; here is what you will have to add to the header to create it.
<link rel="apple-touch-icon" href="images/launch_icon_57.png" /> <link rel="apple-touch-icon" sizes="72x72" href="images/launch_icon_72.png" /> <link rel="apple-touch-icon" sizes="114x114" href="images/launch_icon_114.png" />
You will have to provide a 57, 72 and 114 px width image, for different devices and screen densities.
Conclusion
That’s all folks, today we saw how to create a nice HTML5 jQuery Mobile web app that looks like a native one. Of course this is only the front end part; you will then have to add the server side part, to save data, duplicate pages for each town, etc. But this gives you a nice understanding of how jQuery Mobile works, and what you can do with it.
If you want to see more jQuery Mobile sites, you can take a look at JqmGallery, a nice showcase of webapps and websites built with jQuery Mobile.
Now it’s your turn. Did you ever use jQuery Mobile for a project? If so, don’t hesitate to share the link in the comments, we would love to see what other people are able to do! Have you seen other nice jQuery Mobile sites / apps? Spread the word, and let us know what you think in the comment section.
(rb)