Hello jQuery Mobile

Tweet

In this article I am going to introduce you to jQuery Mobile, hereafter fondly referred to as jQM. We will step through the absolute minimum required to author a website with jQM, touch on some of the preliminary pitfalls, and build up a reference project with which you can hold hands as you take your own first steps.

jQuery Mobile refers to herself as a “touch-optimised web framework for smartphones and tablets”, and further, as “a unified user interface system across all popular mobile device platforms, build on the rock-solid jQuery and jQuery UI foundation”. Essentially, then, author your document using this framework and practically guarantee a good outcome on current mobile devices.

Set Up

Wherein we set up a local development environment for our first experiments. Download jQM, and I would advise that you also download a copy of jQuery, upon which jQM is dependent, to use locally, whether or not you end up using hosted versions in production. Move all of the downloaded files into your project.

I chose to house all of these files in a /jqm/ folder, within the root directory of my project. This is in order to preserve the links between the scripts, CSS and sprite images of the jQM framework. You may choose more traditional /js/ and /css/ and /img/ folders, but maintenance will be required. Bear in mind the fluid nature of the jQM project, and its current alpha state.

Basics

Create your root index.html file, or equivalent. Then if you head over to jQM’s docs and demos, navigate through components, pages & dialogs, to the section explaining the basic anatomy of a page, you will find her boilerplate templates. To get up to speed quickly, copy and paste in a complete single page template, then switch out the for the multi-page snippet.

I have updated the links in the of the document to point to my /jqm/ folder. At this early stage in it’s life, there are a few wrinkles in the boilerplate code, such as comments after the <footer> containers, but they can be forgiven. A few minor tweaks, and I present my own revision of the boilerplate template code.

<!DOCTYPE html> 
<html> 
    <head> 
        <title>Page Title</title> 
        <link rel="stylesheet" href="jqm/jquery.mobile-1.0a4.1.min.css" />
        <script src="jqm/jquery-1.5.2.min.js"></script>
        <script src="jqm/jquery.mobile-1.0a4.1.min.js"></script>
    </head> 
    <body> 
        <!-- Start of first page -->
        <div data-role="page" id="foo">
            <div data-role="header">
                <h1>Foo</h1>
            </div><!-- /header -->
            <div data-role="content">   
                <p>Hi, I'm Foo.</p> 
                <p>I'm first in the source order so I'm shown as the first page.</p>        
                <p>View the internal page called <a href="#bar">Bar</a></p> 
            </div><!-- /content -->
            <div data-role="footer">
                <h4>Page Footer</h4>
            </div><!-- /footer -->
        </div><!-- /page -->
        <!-- Start of second page -->
        <div data-role="page" id="bar">
            <div data-role="header">
                <h1>Bar</h1>
            </div><!-- /header -->
            <div data-role="content">   
                <p>Hello, I'm Bar.</p>  
                <p>I'm second in the source order, and I'm an internal page.</p>        
                <p><a href="#foo">Back to Foo</a></p>   
            </div><!-- /content -->
            <div data-role="footer">
                <h4>Page Footer</h4>
            </div><!-- /footer -->
        </div><!-- /page -->
    </body>
</html>

The documentation of basic page anatomy explains that you can happily link to external pages, and equally happily contain internal pages in the same document. Your choice will be based on common sense factors depending on the site or app you are building, but our reference project will, for simplicity’s sake, house all of its pages internally. We will return to the intricacies later.

For now, note the important structural elements. Each element containing a page includes data-role="page" in the same way that a class="" is added to an element. Each of the pages contains three more elements, one each of a data-role="header" and a data-role="content" and a data-role="footer". This use of data-role="" is how jQM rolls.

Fire up your project right now, with this code in place, to observe the effect of the simple HTML structure with the associated jQM data-role attributes. You should have two linked ‘pages’, slide transitions included for free. For the precocious, try adding additional documents and relevant links, to observe how externals links also ‘just work’ without any special configuration.

Here is the first pro-tip. Add a data-title="" attribute to each data-role="page" container, which will mimic the traditional <title> found in the of an HTML document. Whilst jQM does a fine job of auto-updating page titles for Ajax navigation, on multi-page sites you can add this attribute to manually define the titles, and in so doing help the history stack.

Context

Our reference project is concerned with illuminating how to create various shapes using CSS alone, and zero images. What better context, given our responsible aim to limit the downloads for bandwidth constrained mobile devices, coupled with the opportunity that mobile browsers and their advanced support of CSS3 presents.

The lion’s share of credit for this fancy CSS work goes to Chris Coyier and his Shapes of CSS, and the remainder to his adoring and talented public, for their conversation around and contribution to CSS3 only shapes. Importantly, note that the final version of our reference site does not display all possible shapes, so it is essential you follow the above links and see, first hand, for yourself.

So, in order to illuminate CSS shapes, we will change the boilerplate code so that the first page displays an example of a CSS shape, and the second page displays the CSS required to create that shape out of a single HTML element. But first a diversion into HTML5. The documentation states that a jQM site must start with an HTML5 doctype to take full advantage of the framework.

HTML5

For an in depth guide to HTML5, look no further than HTML5 & CSS3 For the Real World. As I build out our reference site, I will sprinkle in some new HTML5 elements and remove some of the old cruft. Bonus points for calling out, in the comments, where I deviate from the doctrine advocated in the aforementioned book.

  • Change all <div data-role="page"> elements to <section data-role="page">
  • Change all <div data-role="header"> elements to <header data-role="header">
  • Change all <div data-role="content"> elements to <article data-role="content">
  • Change all <div data-role="footer"> elements to <footer data-role="footer">

Let’s ditch the <!-- /header --> type comments, we don’t need them because the markup speaks for itself. We can safely remove type="text/javascript" from script links and type="text/css" from stylesheet links. Sprinkle in a tag, first in the <head>. Finally, note my simple good manners in adhering to unambiguous XHTML style closing slashes.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>CSS3 Shapes</title> 
        <link rel="stylesheet" href="jqm/jquery.mobile-1.0a4.1.min.css" />
        <script src="jqm/jquery-1.5.2.min.js"></script>
        <script src="jqm/jquery.mobile-1.0a4.1.min.js"></script>
    </head>
    <body>
        <section data-role="page" id="infinity" data-title="Infinity">
            <header data-role="header">
                <h1>Infinity</h1>
            </header>
            <article data-role="content">
                <div class="infinity"></div>
                <style>
                    .infinity {
                        position: relative;
                        width: 212px;
                        height: 100px;
                    }

                    .infinity:before,
                    .infinity:after {
                        content: "";
                        position: absolute;
                        top: 0;
                        left: 0;
                        width: 60px;
                        height: 60px;    
                        border: 20px solid #fc2e5a;
                        -moz-border-radius: 50px 50px 0 50px;
                             border-radius: 50px 50px 0 50px;
                        -webkit-transform: rotate(-45deg);
                           -moz-transform: rotate(-45deg);
                            -ms-transform: rotate(-45deg);
                             -o-transform: rotate(-45deg);
                                transform: rotate(-45deg);
                    }

                    .infinity:after {
                        left: auto;
                        right: 0;
                        -moz-border-radius: 50px 50px 50px 0;
                             border-radius: 50px 50px 50px 0;
                        -webkit-transform:rotate(45deg);
                           -moz-transform:rotate(45deg);
                            -ms-transform:rotate(45deg);
                             -o-transform:rotate(45deg);
                                transform:rotate(45deg);
                    }
                </style>
                <p><a href="#infinity_css" data-transition="pop">Infinity CSS</a></p>
            </article>
            <footer data-role="footer">
                <h4>BuildMobile: jQuery Mobile</h4>
            </footer>
        </section><section data-role="page" id="infinity_css" data-title="Infinity">
            <header data-role="header">
                <h1>Infinity</h1>
            </header>
            <article data-role="content">   
                <pre>
                    <code>
.infinity {
    position: relative;
    width: 212px;
    height: 100px;
}

.infinity:before,
.infinity:after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 60px;
    height: 60px;    
    border: 20px solid #fc2e5a;
    -moz-border-radius: 50px 50px 0 50px;
         border-radius: 50px 50px 0 50px;
    -webkit-transform: rotate(-45deg);
       -moz-transform: rotate(-45deg);
        -ms-transform: rotate(-45deg);
         -o-transform: rotate(-45deg);
            transform: rotate(-45deg);
}

.infinity:after {
    left: auto;
    right: 0;
    -moz-border-radius: 50px 50px 50px 0;
         border-radius: 50px 50px 50px 0;
    -webkit-transform:rotate(45deg);
       -moz-transform:rotate(45deg);
        -ms-transform:rotate(45deg);
         -o-transform:rotate(45deg);
            transform:rotate(45deg);
}
                    </code>
                </pre>
                <p><a href="#infinity" data-transition="pop" data-direction="reverse">Infinity Shape</a></p>
            </article>
            <footer data-role="footer">
                <h4>BuildMobile: jQuery Mobile</h4>
            </footer>
        </section>
    </body>
</html>

Transition & Direction

Digging in deeper, note the addition of a data-transition="pop" attribute to the text based links. Add a data-transition attribute to a link to change the default transition from slide, to any of the supported choices including slideup, slidedown, pop, fade and flip. Due to the use of CSS transforms, the animations should be hardware accelerated on many mobile devices.

jQM politely attributes the code for the transitions to jQT, or jQTouch, with some small modifications. jQT was built by David Kaneda and is maintained by Jonathan Stark, and there is no doubt we will publish an introduction to the jQT library here at BuildMobile in the near future, because it offers notable and interesting differences.

Also note the addition of data-direction="reverse" to the link from the second page back to the first. This forces a backwards transition such that the data-transition="pop" shrinks rather than grows. But make careful note that data-direction="reverse" specifies a reverse transition without actually going back in history.

Now is a good time to contemplate the flow pf pages, internal or otherwise, and choose appropriate transitions and directions. There is some advanced documentation on redirects and linking to directories, that we might cover in a later tutorial. Of course, you can read more about the technical details of the navigation model, Ajax, hashes and history in the docs.

Basic List Views

Our reference site contains more than a handful of shapes, so we will add a list for navigation. Add a new container with a data-role="page" and make sure it is the first in the source code. Inside the data-role="content" container, add a <ul> and an <li> for each of our shapes. Because our pages are internal, each <li> should contain an id based href="#shape".

The simple addition of data-role="listview" to the <ul> delivers the jQM magic. The list will be transformed into a full width element, displaying the anchor text to the left and the standard right-arrow icon. Clicking, or tapping any of the links, will trigger the standard right-to-left slide animation into the linked page.

Adding some juice to the list is just as simple. Add data-filter="true" to the <ul> for an instant client side search. Optionally add data-filter-placeholder="" and your chosen placeholder text. The documentation for lists is expansive, but you will find advanced functionality is simple to achieve, and follows the same patterns as we have covered thus far.

Notes on Navigation

Our reference site has a navigation page, nine ‘shape’ pages, each of which has a ‘CSS’ page. All bar the first has a ‘back’ button added automatically by the jQM framework, which comes as standard with the data-role="header". But without intervention, it is flawed and breaks the mental model.

If you were to toggle between the ‘shape’ and the ‘CSS’ page several times, each transition would be added to the history stack. Clicking the ‘back’ button would reverse that history and toggle between the ‘shape’ and ‘CSS’ pages as many times, before finally going back the the navigation page where you started.

So we add data-rel="back" to the link, which mimics the back button, going back one history item and ignoring the anchor’s default href. Despite being ignored, it is important to add a meaningful href that actually points to the URL of the referring page, so that C-grade browsers can follow it, and the flow doesn’t break.

I predict this will change, we may not even get the ‘back’ button by default in future. Again I point you back to the documentation on the navigation model. For now, be aware that a link from an Ajax loaded page into multiple internal pages requires the addition of rel="external" or data-ajax="false" to do a full reload clearing the Ajax hash in the URL.

Closing

Not a single line of CSS was written in the making of the ‘Shapes’ reference site, besides the CSS in the content of course, which I am discounting. Zero images were required, besides the existent sprites in the jQM framework. The total weight of the jQM framework, and the jQuery library on which it depends, is approximately 234KB plus just 20KB for our reference document.

Time has almost run out, and in this article we have merely scratched the surface in touching on just some of the documentation of pages and dialogs, toolbars and list views. The documentation is easy to follow on your own, but you might want to request additional coverage of buttons, forms, and general content formatting, in the comments.

In a future article I will dive deeper, wherein the various aspects of the API are covered. But for now, let’s do some crowd sourced guerilla testing. Fire up the reference site on your mobile, be that an Android phone, and iPhone or an iPad, and tell the world what is and is not working. I will try and address the points raised in the next instalment.

Extra Credits

Make a site behave more like an app with the inclusion of a in the of the document. This only works when the site is added to the home screen. The old skool method was to remove the chrome with the addition of onload="setTimeout(function() { window.scrollTo(0, 1) }, 100); to the tag.

Better still, add to the for non retina smartphones, and drop the PNG into the root directory. Then add to the and the PNG in the root for a retina display.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Steve

    Great write-up. I actually just started using jQuery Mobile today and had my first mobile website up and running in a couple hours.

    There was one question that I couldn’t seem to find an answer to though and that was, how do you add the home button the the headers of internally loaded pages? In my instance, I had nested lists and when you would go down a level, you would only have a back button and the page title in the header.

    • http://buildmobile.com Paul Bridgestock

      Steve, there are slots for buttons either side of the text heading in the data-role="header". An anchor element or any valid button markup will do. Select the icon to use by adding data-icon="home" and you will probably need to add class="ui-btn-right" to your anchor, to avoid overwriting the default ‘back’ button.

  • http://www.revitalagency.com Wayne Roddy

    I used this framework on m.cafealma.com . It’s a great tool for quick mobile ready styles and code. Just one tip: if you use the anchor names and page IDs like they use you won’t get any tracking in analytics. Just add the on click event tracking code from GA to get some segmenting.
    For Example: Call 727-502-5002

    • http://buildmobile.com Paul Bridgestock

      Wayne, thanks for that tip, its a very good one. Unfortunately, our comments engine stripped out some of your example code, but for the benefit of the readers I think you are referring to Asynchronous Tracking as explained in the Google Analytics documentation.

  • Brent

    Cool article, thanks. Have you integrated Boilerplate Mobile into jQM yet? Or know of an example?

    http://html5boilerplate.com/mobile/

    thx!

    • http://buildmobile.com Paul Bridgestock

      Brent, thank you for the nice feedback. I have not integrated the Mobile Boilerplate yet, because I wanted to keep the article code simple and focussed on jQM. Mobile Boilerplate is big enough and cool enough to demand a dedicated post of its own, would that be something you are interested in reading?

      • http://www.gabrielpeyrot.com Gabriel

        Great article, thank you Paul. It has just given me a great kick start for JQuery-Mobile. =]

      • http://www.mobilewebkit.com Brent

        Yes, I think most webdevs are looking for the best, most stable path forward with the mobile web. Yet as we know, it’s a mine-field. If integration of those two is the best way, I would love to read your thoughts.

        One question. Does your removing DIVs and replacing them with HTML5 SECTION tags change the overall mobile device compatibility that jQM is supposed to cover?

        Thank you !!!

    • http://buildmobile.com Paul Bridgestock

      Not suggesting the combination of jQM and the Mobile Boilerplate is the best way, because there is no best way. As usual the choices will be based on the project and its needs. Also, I wouldn’t describe it as a minefield, rather a candy store.

      HTML5 support is varied across the entire spectrum of mobile devices, so I would have to answer in the affirmative; this probably would change the compatibility that jQM offers. This demo is forward thinking, and targets right up to date mobile devices.

  • ajaz

    @ Paul Bridgestock: Loads of thanks for such a nice writeup. I just want to ask a simple query regarding the above writeup. Can I divide the ‘content’ (i.e. data-role=’content’) into number of sections? If Yes, how could I achieve it? Can I use my own style -sheet in addition to the built-in style-sheet?

    Thanks

  • ajaz

    @ Paul Bridgestock: Anyways I figured it out and I can use style sheets the way we use with normal web pages meant for desktop.
    Thanks
    ajaz

    • http://buildmobile.com Paul Bridgestock

      Hello Ajaz, thanks so much for your nice comments. Pleased to hear you have figured out your issue, let us know what you did. Also, I plan to write an article on styling or theming jQM in the near future.

  • http://aarontgrogg.com/ Aaron T. Grogg

    “The total weight of the jQM framework, and the jQuery library on which it depends, is less than 500KB…”

    I do hope this is a typo, and that we’re not really talking so flippantly about pushing half-a-MB to our mobile users?

    Otherwise, great intro, cheers,
    Atg

    • http://buildmobile.com Paul Bridgestock

      Hey Aaron, absolutely a typo and thanks for calling me out on it (actually it was an arbitrary number I never went back to update). Putting the framework back on the scales we have minified CSS (45KB), minified Javascript (66KB), a folder of sprites (37KB) and minified jQuery herself (86KB) for a total of 234KB. On top of that my example HTML file weighs 20KB. Then I have three variant touch icons at 4KB each. Total web app so far 266KB.

  • http://www.mglc-design.com mel

    I have been researching getting my sites mobile, this was a great write up, thank you

  • http://www.mobilewebkit.com Brent

    You have some typos in the article. You write “data-transion” a few times and it should be “data-transition”.

    • http://buildmobile.com Paul Bridgestock

      Brent, I have fixed up those typos and I thank you for pointing them out. It seems you have a keen eye for the details, perhaps you should consider writing for us? Check out our about and contribute pages for the details. Seriously.

  • turin

    “Digging in deeper, note the addition of a data-transition=”pop” attribute to the text based links. Add a data-transition attribute to a link to change the default transition from slide, to any of the supported choices including slideup, slidedown, pop, fade and flip. Due to the use of CSS transforms, the animations should be hardware accelerated on many mobile devices.”

    I am not noticing any hardware acceleration at all. The cpu spikes on a webkit based browser
    for slideup and flip. Doing the same exact kind of transformations using pure CSS3 transforms and animations kept the CPU low. Are they missing ” -webkit-transform-style: preserve-3d;
    ” in the JQM css files or guaranteeing hardware accelration with ” -webkit-transform: translateZ(0);”

  • turin

    ie: there is no preserv3d anywhere and the only class with translateZ(0) is

    .ui-header-fixed,.ui-footer-fixed {
    z-index:1000;
    -webkit-transform:translateZ(0);
    }

    does this mean in order to have hardware acceleration you have to enclose your content in a header and footer?

  • http://jitendravyas.com Jitendra Vyas

    Very informative article. I was new to jQuery Mobile and searching on Google to get a Good Intro. I found many links but this article impressed me.

    I have one question when we add multiple page in single page is it OK for SEO and Accessibility?