The jQuery Mobile "page" structure is optimized to support either single pages, or local internal linked "pages" within a page.
The goal of this model is to allow developers to create websites using best practices — where ordinary links will "just work" without any special configuration — while creating a rich, native-like experience that can't be achieved with standard HTTP requests.
A jQuery Mobile site must start with an HTML5 'doctype' to take full advantage of all of the framework's features. (Older devices with browsers that don't understand HTML5 will safely ignore the 'doctype' and various custom attributes.) In the 'head', references to jQuery, jQuery Mobile and the mobile theme CSS are all required to start things off. We recommend linking to the files hosted on the jQuery CDN for best performance:
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.css" />
<script type="text/javascript" src="https://code.jquery.com/jquery-1.6.3.min.js"></script>
<script type="text/javascript" src="https://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.js"></script>
</head>
<body>
...content goes here...
</body>
</html>
Note above that there is a meta viewport
tag in the head
to specify how the browser should display the page zoom level and dimensions. If this isn't set, many mobile browsers will use a "virtual" page width around 900 pixels to make it work well with exisitng desktop sites but the screens may look zoomed out and too wide. By setting the viewport attributes to content="width=device-width, initial-scale=1
, the width will be set to the pixel width of the device screen.
<meta name="viewport" content="width=device-width, initial-scale=1">
These settings do not disable the user's ability to zoom the pages which is nice from an accessibility perspective. There is a minor issue in iOS that doesn't properly set the width when changing orientations with these viewport settings, but this will hopefully be fixed a a future release. You can set other viewport values to disable zooming if required since this is part of your page content, not the library.
Inside the <body>
tag, each view or "page" on the mobile device is identified with an element (usually a div
) with the data-role="page"
attribute:
<div data-role="page">
...
</div>
Within the "page" container, any valid HTML markup can be used, but for typical pages in jQuery Mobile, the immediate children of a "page" are divs with data-roles of "header"
, "content"
, and "footer"
.
<div data-role="page">
<div data-role="header">...</div>
<div data-role="content">...</div>
<div data-role="footer">...</div>
</div>
Putting it all together, this is the standard boilerplate page template you should start with on a project. :
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.css" />
<script type="text/javascript" src="https://code.jquery.com/jquery-1.6.3.min.js"></script>
<script type="text/javascript" src="https://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.js"></script>
</head>
<body>
<div data-role="page">
<div data-role="header">
<h1>Page Title</h1>
</div><!-- /header -->
<div data-role="content">
<p>Page content goes here.</p>
</div><!-- /content -->
<div data-role="footer">
<h4>Page Footer</h4>
</div><!-- /footer -->
</div><!-- /page -->
</body>
</html>
View boilerplate template
A single HTML document can contain multiple 'pages' that are loaded together by stacking multiple divs with a data-role
of "page"
. Each 'page' block needs a unique ID (id="foo"
) that will be used to link internally between 'pages' (href="#foo"
). When a link is clicked, the framework will look for an internal 'page' with the ID and transition it into view.
Here is an example of a 2 "page" site built with two jQuery Mobile divs navigated by linking to an ID placed on each page wrapper. Note that the IDs on the page wrappers are only needed to support the internal page linking, and are optional if each page is a separate HTML document. Here is what two pages look inside the body
element.
<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>I'm first in the source order so I'm shown as the page.</p>
<p>View 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>I'm first in the source order so I'm shown as the 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>
View multi-page template
PLEASE NOTE: Since we are using the hash to track navigation history for all the Ajax 'pages', it's not currently possible to deep link to an anchor (index.html#foo
) on a page in jQuery Mobile, because the framework will look for a 'page' with an ID
of #foo
instead of the native behavior of scrolling to the content with that ID
.
Although the page structure outlined above is a recommended approach for a standard web app built with jQuery Mobile, the framework is very flexible with document structure. The page, header, content, and footer data-role elements are optional and are mostly helpful for providing some basic formatting and structure. The page wrapper used to be required for auto-initialization to work but this too is now optional for single page documents so there isn't any required markup at all. For a web page with a custom layout, all of these structural elements can be omitted but the Ajax navigation and all widgets will work just like they do in the boilerplate structure. Behind the scenes, the framework will inject the page wrapper if it's not included in the markup because it’s needed for managing pages, but the starting markup can now be extremely simple.
Note that in a multi-page setup, you are required to have page wrappers in your markup in order to group the content into multiple pages.