Skip to content

jQuery Mobile チートシート

Touch-optimized HTML5 UI framework for mobile web apps.

01

Getting Started

Page Structure

jQuery Mobile uses data-role attributes to enhance HTML. A page is a div with data-role=page containing header, main, and footer sections. The viewport meta tag is essential for proper scaling on mobile devices. Load jQuery core before jquery.mobile.js.

jquery-mobile
<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css">
  <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
  <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
</head>
<body>
  <div data-role="page" id="home">
    <div data-role="header"><h1>Home</h1></div>
    <div data-role="main" class="ui-content">Content</div>
    <div data-role="footer"><h4>Footer</h4></div>
  </div>
</body>
</html>

Multiple Pages in One Document

You can place multiple data-role=page divs in a single HTML file. Link between them with anchor hrefs (#about). jQuery Mobile shows one page at a time and animates transitions. Only the first page in source order is shown on initial load.

jquery-mobile
<div data-role="page" id="home">
  <div data-role="header"><h1>Home</h1></div>
  <div data-role="main" class="ui-content">
    <a href="#about" class="ui-btn">Go to About</a>
  </div>
</div>

<div data-role="page" id="about" data-theme="b">
  <div data-role="header"><h1>About</h1></div>
  <div data-role="main" class="ui-content">
    <a href="#home" class="ui-btn" data-direction="reverse">Back</a>
  </div>
</div>

AJAX Navigation & Links

By default, links to internal (#id) and same-origin pages are fetched via AJAX and swapped with a transition. Use data-ajax=false to force a normal full-page load (useful for non-jQuery Mobile pages). data-prefetch preloads the target so the transition is instant.

jquery-mobile
<!-- Default: links load via AJAX and animate a transition -->
<a href="detail.html" class="ui-btn">Open detail (AJAX)</a>

<!-- Force a full page reload (no AJAX) -->
<a href="external.html" data-ajax="false">Full reload</a>

<!-- Open in new window/tab -->
<a href="https://example.com" rel="external">External site</a>

<!-- Prefetch a page when this page loads -->
<a href="next.html" data-prefetch="true" class="ui-btn">Prefetch next</a>

Prefetching & DOM Caching

Prefetching loads linked pages in the background so navigation feels instant. By default visited pages are removed from the DOM, but domCache keeps them for faster back-navigation at the cost of memory. Enable per-page with data-dom-cache or globally via the page prototype option.

jquery-mobile
<!-- Prefetch several pages -->
<a href="page1.html" data-prefetch="true">Page 1</a>
<a href="page2.html" data-prefetch="true">Page 2</a>

<!-- Globally enable DOM caching of visited pages -->
<script>
$(document).on("mobileinit", function () {
  $.mobile.page.prototype.options.domCache = true;
});
</script>

<!-- Cache a single page -->
<div data-role="page" id="cached" data-dom-cache="true">...</div>

Dialog Pages

Add data-rel=dialog to a link (or data-dialog=true on the page) to open a page styled as a modal dialog with a close button and transition. Use data-rel=back on a link to close it and return to the previous page.

jquery-mobile
<!-- Open a page as a dialog -->
<a href="#dialog" class="ui-btn" data-rel="dialog">Open dialog</a>

<div data-role="page" id="dialog" data-dialog="true">
  <div data-role="header"><h1>Dialog</h1></div>
  <div data-role="main" class="ui-content">
    <p>This page is styled as a dialog.</p>
    <a href="#" class="ui-btn" data-rel="back">Close</a>
  </div>
</div>

Global Configuration (mobileinit)

The mobileinit event fires after jQuery core loads but before jQuery Mobile initializes — bind your config here, before including jquery.mobile.js. Common overrides: default transitions, AJAX settings, and loading message text. Setting autoInitializePage=false lets you control when the first page initializes.

jquery-mobile
<script src="jquery-1.11.1.min.js"></script>
<script>
// Bind BEFORE loading jquery.mobile.js
$(document).on("mobileinit", function () {
  $.mobile.defaultPageTransition = "slide";
  $.mobile.defaultDialogTransition = "pop";
  $.mobile.loadingMessage = "Loading...";
  $.mobile.ajaxEnabled = true;
  $.mobile.linkBindingEnabled = true;
  $.mobile.autoInitializePage = true;
});
</script>
<script src="jquery.mobile-1.4.5.min.js"></script>
02

Page Transitions

Basic Transitions

Add data-transition to a link to choose the animation when navigating. Transitions are CSS-based (hardware-accelerated where possible). 'none' skips animation for instant navigation. The same attribute works for dialogs and popups.

jquery-mobile
<!-- Apply a transition to a link -->
<a href="#page2" data-transition="slide">Slide</a>
<a href="#page2" data-transition="fade">Fade</a>
<a href="#page2" data-transition="pop">Pop</a>
<a href="#page2" data-transition="flip">Flip</a>
<a href="#page2" data-transition="none">None (instant)</a>

Transition Types

jQuery Mobile ships with a set of 2D/3D CSS transitions. 3D transitions (turn, flow, flip) look great on capable devices but fall back gracefully on older hardware. pop and fade are the most performant and are recommended for dialogs and popups.

jquery-mobile
<!-- Available transitions in jQuery Mobile 1.4 -->
fade      <!-- default, fade in/out -->
pop       <!-- scale in from center (good for dialogs) -->
slide     <!-- slide left to right -->
slideup   <!-- slide up from bottom -->
slidedown <!-- slide down from top -->
slidfade  <!-- slide + fade -->
turn      <!-- 3D turn -->
flow      <!-- 3D flow -->
flip      <!-- 3D flip -->
none      <!-- no animation -->

Direction & Reverse

data-direction=reverse plays the transition backwards — typically used on Back buttons so the animation mirrors the forward navigation. This pairs with data-transition; if no transition is set, the default is reversed.

jquery-mobile
<!-- Reverse a transition (e.g., for Back buttons) -->
<a href="#home" data-transition="slide" data-direction="reverse">Back</a>

<!-- Globally reverse the default -->
<a href="#home" data-direction="reverse">Back (uses default transition reversed)</a>

Dialog Transitions

Dialogs can use any transition, but pop and slidedown feel most natural for modals. Set a global default with $.mobile.defaultDialogTransition during mobileinit. The dialog's close action reverses the transition automatically.

jquery-mobile
<!-- Combine data-rel=dialog with a transition -->
<a href="#settings" data-rel="dialog" data-transition="pop">Settings</a>
<a href="#settings" data-rel="dialog" data-transition="slidedown">Settings (slide down)</a>

<!-- Set a global default dialog transition -->
<script>
$(document).on("mobileinit", function () {
  $.mobile.defaultDialogTransition = "pop";
});
</script>

Disabling & Fallback

Set data-transition=none or the global default to 'none' to disable animations — helpful on low-end devices or for accessibility. jQuery Mobile automatically detects 3D transform support and degrades 3D transitions (flip, turn, flow) to a simple fade when unsupported.

jquery-mobile
<!-- Disable transitions for a specific link -->
<a href="#page2" data-transition="none">No animation</a>

<!-- Globally disable (useful for older devices / testing) -->
<script>
$(document).on("mobileinit", function () {
  $.mobile.defaultPageTransition = "none";
  $.mobile.defaultDialogTransition = "none";
});
</script>

<!-- 3D transitions fall back to fade when not supported -->
03

Toolbars (Header & Footer)

Fixed Header & Footer

Add data-position=fixed to keep a header or footer pinned at the top/bottom of the viewport while the page scrolls. Tapping the page toggles the toolbars' visibility by default. The page content gets padding so it isn't hidden behind the toolbars.

jquery-mobile
<div data-role="page" id="home">
  <div data-role="header" data-position="fixed">
    <h1>Fixed Header</h1>
  </div>
  <div data-role="main" class="ui-content">
    <p>Scroll the page — the toolbars stay in place.</p>
  </div>
  <div data-role="footer" data-position="fixed">
    <h4>Fixed Footer</h4>
  </div>
</div>

Fullscreen Toolbars

data-fullscreen=true overlays the fixed toolbars on top of the content (semi-transparent), instead of reserving space. Great for photo viewers or maps where content should fill the screen. The toolbars appear/disappear on tap just like fixed toolbars.

jquery-mobile
<div data-role="page" id="photo">
  <div data-role="header" data-position="fixed" data-fullscreen="true">
    <h1>Photos</h1>
  </div>
  <div data-role="main" class="ui-content">
    <img src="photo.jpg" style="width:100%">
  </div>
  <div data-role="footer" data-position="fixed" data-fullscreen="true">
    <h4>Footer over content</h4>
  </div>
</div>

Persistent Toolbars

When two pages have footers (or headers) with the same data-id and data-position=fixed, the toolbar persists across page transitions instead of animating with the page. This is the standard pattern for a persistent bottom navigation bar — only the active link changes per page.

jquery-mobile
<!-- Both pages use the SAME data-id so the footer persists -->
<div data-role="page" id="home">
  <div data-role="footer" data-id="main-nav" data-position="fixed">
    <div data-role="navbar">
      <ul><li><a href="#home" class="ui-btn-active">Home</a></li>
      <li><a href="#settings">Settings</a></li></ul>
    </div>
  </div>
</div>

<div data-role="page" id="settings">
  <div data-role="footer" data-id="main-nav" data-position="fixed">
    <div data-role="navbar">
      <ul><li><a href="#home">Home</a></li>
      <li><a href="#settings" class="ui-btn-active">Settings</a></li></ul>
    </div>
  </div>
</div>

Tap Toggle Behavior

Fixed toolbars toggle visibility when the user taps the page. Set data-tap-toggle=false to keep a toolbar always visible. Related per-element options: data-hide-during-focus (hide when inputs are focused) and data-update-page-padding (re-apply page padding on resize).

jquery-mobile
<!-- Disable tap-to-toggle on a fixed toolbar -->
<div data-role="header" data-position="fixed" data-tap-toggle="false">
  <h1>Always visible</h1>
</div>

<!-- Globally turn off tap toggle -->
<script>
$(document).on("mobileinit", function () {
  $.mobile.toolbar.prototype.options.tapToggle = false;
});
</script>

Toolbar Theme & Buttons

Headers can hold buttons positioned with the ui-btn-left / ui-btn-right classes. data-theme sets the color swatch of the bar. data-iconpos=notext shows only an icon for a compact look. Buttons inside a header are auto-styled as inline buttons.

jquery-mobile
<div data-role="header" data-theme="b">
  <a href="#" class="ui-btn-left" data-icon="home" data-iconpos="notext">Home</a>
  <h1>Title</h1>
  <a href="#" class="ui-btn-right" data-icon="gear" data-iconpos="notext">Settings</a>
</div>

Dynamically Updating Toolbars

After changing toolbar markup at runtime, call $(el).toolbar('refresh') to re-apply styling and padding. The toolbar widget (introduced in 1.4) manages fixed positioning and tap-toggle; initialize it manually with $().toolbar() if you add a toolbar after page create.

jquery-mobile
<script>
// Update the header title and re-enhance after DOM change
$(function () {
  $("#my-header h1").text("New Title");
  $("#my-header").toolbar("refresh");
});
</script>

<div data-role="header" id="my-header" data-position="fixed">
  <h1>Old Title</h1>
</div>
05

Buttons

Button Basics

Any <a> with class=ui-btn (or data-role=button), plus <button> and <input type=button|submit|reset>, are auto-enhanced into styled buttons. The ui-btn class is the modern way to mark a link as a button without relying on data-role.

jquery-mobile
<!-- Anchor button -->
<a href="#" class="ui-btn">Link Button</a>

<!-- <button> and <input> auto-enhanced -->
<button class="ui-btn">Button Element</button>
<input type="button" value="Input Button">
<input type="submit" value="Submit">

<!-- Use data-role explicitly -->
<a href="#" data-role="button">Anchor via role</a>

Inline Buttons

By default buttons are full-width (block). Add ui-btn-inline (or data-inline=true) to make a button only as wide as its label, so multiple buttons sit side by side. This is useful for action rows like 'Cancel | OK'.

jquery-mobile
<!-- Inline: only as wide as the content -->
<a href="#" class="ui-btn ui-btn-inline">A</a>
<a href="#" class="ui-btn ui-btn-inline">B</a>
<a href="#" class="ui-btn ui-btn-inline">C</a>

<!-- Default (block) buttons fill the width -->
<a href="#" class="ui-btn">Full-width button</a>

Button Icons

Use ui-icon-{name} to add an icon and ui-btn-icon-{pos} to place it (left, right, top, bottom, notext). ui-btn-icon-notext hides the text and shows only the icon — provide text anyway for accessibility/screen readers.

jquery-mobile
<a href="#" class="ui-btn ui-icon-home ui-btn-icon-left">Home</a>
<a href="#" class="ui-btn ui-icon-search ui-btn-icon-right">Search</a>
<a href="#" class="ui-btn ui-icon-gear ui-btn-icon-top">Settings</a>
<a href="#" class="ui-btn ui-icon-star ui-btn-icon-notext">Star (icon only)</a>
<a href="#" class="ui-btn ui-icon-delete ui-btn-icon-bottom">Delete</a>

Icon Position & Inline

The data-iconpos attribute is the legacy equivalent of the ui-btn-icon-* classes. 'notext' shows only the icon (always keep visible text for screen readers via the element text). You can freely combine inline and icon classes on one button.

jquery-mobile
<!-- data-* equivalents -->
<a href="#" data-role="button" data-icon="home" data-iconpos="left">Home</a>
<a href="#" data-role="button" data-icon="home" data-iconpos="notext">Home</a>

<!-- Combine inline + icon -->
<a href="#" class="ui-btn ui-btn-inline ui-icon-plus ui-btn-icon-left">Add</a>
<a href="#" class="ui-btn ui-btn-inline ui-icon-minus ui-btn-icon-left">Remove</a>

Mini & Disabled Buttons

Add ui-mini (or data-mini=true) for a smaller, more compact button — useful in dense toolbars. Disable a button with ui-state-disabled (or the native disabled attribute on <button>/<input>). Disabled buttons ignore taps.

jquery-mobile
<!-- Mini (smaller) button -->
<a href="#" class="ui-btn ui-mini">Mini</a>

<!-- Disabled button -->
<a href="#" class="ui-btn ui-state-disabled">Disabled</a>

<!-- Native disabled -->
<button disabled>Disabled button</button>
<input type="submit" value="Go" disabled>

Button Groups (Controlgroup)

A controlgroup clusters buttons visually — adjacent buttons share rounded corners and no gaps. data-type=horizontal arranges them in a row (good for segmented controls); the default vertical stacks them. This also groups checkboxes/radios into a unified set.

jquery-mobile
<div data-role="controlgroup" data-type="horizontal">
  <a href="#" class="ui-btn">Yes</a>
  <a href="#" class="ui-btn">No</a>
  <a href="#" class="ui-btn">Maybe</a>
</div>

<!-- Vertical group (default) -->
<div data-role="controlgroup">
  <a href="#" class="ui-btn">Option 1</a>
  <a href="#" class="ui-btn">Option 2</a>
</div>
06

List Views

Basic Listview

Add data-role=listview to a <ul> to turn it into a touch-friendly list with full-width tappable rows. Each <li> containing an <a> becomes a linked row with a right arrow. data-inset=true insets the list with rounded corners and margins instead of edge-to-edge.

jquery-mobile
<ul data-role="listview" data-inset="true">
  <li><a href="#">Apple</a></li>
  <li><a href="#">Banana</a></li>
  <li><a href="#">Cherry</a></li>
</ul>

Inset Lists

Edge-to-edge lists span the full width (good for full-screen menus); inset lists have rounded corners and surrounding margins (good for content sections within a page). Use data-inset=true for inset lists, which look more like grouped settings panels.

jquery-mobile
<!-- Edge-to-edge (default) -->
<ul data-role="listview">
  <li><a href="#">Item 1</a></li>
</ul>

<!-- Inset: rounded, with margins -->
<ul data-role="listview" data-inset="true">
  <li><a href="#">Item 1</a></li>
  <li><a href="#">Item 2</a></li>
</ul>

List Dividers

An <li> with data-role=list-divider becomes a non-clickable section header. data-autodividers=true automatically inserts dividers based on the first letter of each item's text — perfect for an alphabetical contact list.

jquery-mobile
<ul data-role="listview" data-inset="true">
  <li data-role="list-divider">Fruits</li>
  <li><a href="#">Apple</a></li>
  <li><a href="#">Banana</a></li>
  <li data-role="list-divider">Vegetables</li>
  <li><a href="#">Carrot</a></li>
</ul>

<!-- Auto dividers from first letter -->
<ul data-role="listview" data-autodividers="true">
  <li><a href="#">Alice</a></li>
  <li><a href="#">Bob</a></li>
</ul>

Count Bubbles & Thumbnails

Add a span with class=ui-li-count inside an <li> to show a numeric count bubble on the right. Use an <img> with class=ui-li-thumb (typically 80x80) for a left thumbnail. Combine with <h3>/<p> for rich, app-like list rows.

jquery-mobile
<ul data-role="listview" data-inset="true">
  <!-- Count bubble -->
  <li><a href="#">Inbox <span class="ui-li-count">12</span></a></li>
  <!-- Thumbnail on the left -->
  <li>
    <a href="#">
      <img src="thumb.jpg" class="ui-li-thumb">
      <h3>Title</h3>
      <p>Description</p>
      <span class="ui-li-count">3</span>
    </a>
  </li>
</ul>

Search Filter

data-filter=true adds a search input above the list that filters items by text in real time. data-filter-placeholder customizes the prompt. data-filter-reveal=true hides all items until the user types — useful for an autocomplete-style lookup.

jquery-mobile
<ul data-role="listview" data-filter="true"
    data-filter-placeholder="Search fruits...">
  <li><a href="#">Apple</a></li>
  <li><a href="#">Banana</a></li>
  <li><a href="#">Cherry</a></li>
</ul>

<!-- Filter reveals hidden items (collapsible search) -->
<ul data-role="listview" data-filter="true" data-filter-reveal="true">
  <li><a href="#">Hidden until searched</a></li>
</ul>

Split Buttons & Nested Lists

When an <li> contains two <a> elements, jQuery Mobile renders a split button: the main row navigates to the first link, and a separate icon button (set via data-split-icon) on the right opens the second. A nested <ul> inside an <li> becomes a drill-down sub-page automatically.

jquery-mobile
<!-- Split button: row link + icon link on the right -->
<ul data-role="listview" data-split-icon="gear" data-inset="true">
  <li>
    <a href="#detail">Go to detail</a>
    <a href="#edit">Edit</a>
  </li>
</ul>

<!-- Nested list (child <ul> becomes a sub-page) -->
<ul data-role="listview">
  <li>Fruits
    <ul>
      <li><a href="#">Apple</a></li>
      <li><a href="#">Banana</a></li>
    </ul>
  </li>
</ul>
07

Form Controls

Form Structure & AJAX Submission

jQuery Mobile auto-enhances form inputs and submits forms via AJAX by default, showing a loading spinner and transitioning to the result page. Set data-ajax=false to do a traditional full-page submit (required for file uploads that don't use a modern API).

jquery-mobile
<form action="/submit" method="post" data-ajax="true">
  <label for="name">Name:</label>
  <input type="text" name="name" id="name" placeholder="Your name">

  <button type="submit" class="ui-btn">Submit</button>
</form>

<!-- Disable AJAX for this form (normal full submit) -->
<form action="/upload" method="post" data-ajax="false">...</form>

Text Inputs & Clear Button

All HTML5 input types (text, email, tel, number, password, date, etc.) are styled consistently. data-clear-btn=true adds an in-field clear (x) button. Use data-role=none to keep a control as a plain native input without jQuery Mobile styling.

jquery-mobile
<label for="email">Email</label>
<input type="email" id="email" data-clear-btn="true" placeholder="[email protected]">

<label for="phone">Phone</label>
<input type="tel" id="phone" data-clear-btn="true" data-clear-btn-text="Clear">

<!-- Non-enhanced native input -->
<input type="text" data-role="none">

Field Containers

Wrap a label + control pair in a div with class=ui-field-contain. On wide screens the label and input sit side by side; on narrow phones they stack vertically. This responsive behavior replaces the older data-role=fieldcontain attribute.

jquery-mobile
<div class="ui-field-contain">
  <label for="user">Username</label>
  <input type="text" id="user">
</div>

<div class="ui-field-contain">
  <label for="pwd">Password</label>
  <input type="password" id="pwd">
</div>

Search Input

An <input type=search> is enhanced into a search field with a magnifying-glass icon. Pair it with a listview by giving the input an id and setting data-input=#id on the listview's filter — this lets you place the search box anywhere on the page.

jquery-mobile
<label for="q">Search</label>
<input type="search" id="q" placeholder="Search...">

<!-- Search input feeding a listview filter -->
<input type="search" id="my-filter" data-type="search">
<ul data-role="listview" data-filter="true"
    data-input="#my-filter">
  <li><a href="#">Apple</a></li>
  <li><a href="#">Banana</a></li>
</ul>

Textarea & Hidden Inputs

Textareas are styled to match other inputs and auto-grow as you type by default; set data-autogrow=false to fix the height with a scrollbar instead. Hidden inputs are passed through untouched. Like all inputs, wrap them in ui-field-contain for responsive labels.

jquery-mobile
<label for="bio">Bio</label>
<textarea id="bio" placeholder="Tell us about you"></textarea>

<!-- Auto-grow textarea -->
<textarea id="bio" data-autogrow="false"></textarea>

<!-- Hidden inputs are not styled -->
<input type="hidden" name="id" value="42">

Disabling Auto-enhancement

Add data-role=none to any control to skip jQuery Mobile enhancement and keep it native. For a project-wide rule, set keepNative during mobileinit to a selector string of elements that should never be enhanced — useful when mixing custom-styled controls with jQM pages.

jquery-mobile
<!-- Keep a control native (no jQM styling) -->
<select data-role="none">...</select>
<input type="checkbox" data-role="none">

<!-- Globally disable enhancement for a tag -->
<script>
$(document).on("mobileinit", function () {
  $.mobile.page.prototype.options.keepNative = "select, input[type=checkbox]";
});
</script>
08

Sliders

Basic Range Slider

An <input type=range> with min, max, value, and step is enhanced into a touch-friendly slider with a value bubble. The value attribute sets the initial position. The slider writes its value back to the input, so it submits normally with the form.

jquery-mobile
<label for="volume">Volume</label>
<input type="range" name="volume" id="volume"
       value="50" min="0" max="100" step="1">

Slider with Highlight

data-highlight=true fills the track to the left of the handle with the active theme color, giving a clear visual of the current level. Without it the track is a single flat color. Useful for settings like volume or brightness.

jquery-mobile
<label for="brightness">Brightness</label>
<input type="range" id="brightness"
       value="70" min="0" max="100"
       data-highlight="true">

Mini Slider

data-mini=true renders a smaller, more compact slider that takes less vertical space — handy when grouping several controls in a settings panel. It behaves identically to the regular slider, just at a reduced size.

jquery-mobile
<label for="age">Age</label>
<input type="range" id="age" value="25" min="0" max="120"
       data-mini="true" data-highlight="true">

Step & Multiple Sliders

step controls the increment (e.g., step=5 snaps to 0, 5, 10, ...). Each range input is an independent slider; for a dual-handle range you must build a custom widget or use a third-party plugin. The native value, min, max attributes drive the behavior.

jquery-mobile
<label for="temp">Temperature (step 5)</label>
<input type="range" id="temp" value="20" min="0" max="100" step="5">

<!-- Two independent sliders -->
<label for="low">Min</label>
<input type="range" id="low" value="10" min="0" max="100">
<label for="high">Max</label>
<input type="range" id="high" value="90" min="0" max="100">

Slider Events

The slider emits slidestart when the user begins dragging the handle and slidestop when the drag ends. For continuous updates during the drag, bind to the native 'input' or 'change' event on the underlying range input. Read/write the value with $(el).val().

jquery-mobile
<label for="vol">Volume</label>
<input type="range" id="vol" value="50" min="0" max="100">

<script>
$("#vol").on("slidestart", function () {
  console.log("User started dragging");
});
$("#vol").on("slidestop", function () {
  console.log("Value is now " + $(this).val());
});
</script>
09

Flip Toggle Switches

Basic Flip Toggle

A flip switch is a <select> with exactly two <option> elements and data-role=slider. It renders as an iOS-style on/off toggle. The selected option determines the initial state, and the value submits like a normal select (the value of the chosen option).

jquery-mobile
<label for="notify">Notifications</label>
<select name="notify" id="notify" data-role="slider">
  <option value="off">Off</option>
  <option value="on" selected>On</option>
</select>

Custom Labels

The text of the two options becomes the labels on each side of the switch. You can use any short text (On/Off, Yes/No, Enabled/Disabled). Keep labels short so they fit within the toggle without truncation on small screens.

jquery-mobile
<label for="wifi">Wi-Fi</label>
<select id="wifi" data-role="slider">
  <option value="disabled">Disabled</option>
  <option value="enabled" selected>Enabled</option>
</select>

Mini Flip Switch

data-mini=true renders a smaller flip switch that takes less vertical space, matching mini sliders and other mini controls. Pair mini controls together in dense settings panels for a consistent compact look.

jquery-mobile
<label for="sync">Auto-sync</label>
<select id="sync" data-role="slider" data-mini="true">
  <option value="no">No</option>
  <option value="yes" selected>Yes</option>
</select>

Flip Theme

data-theme sets the color of the switch handle, and data-track-theme sets the color of the track behind it. Mixing swatches (e.g., a dark handle on a light track) makes the active state more visually distinct.

jquery-mobile
<label for="darkmode">Dark mode</label>
<select id="darkmode" data-role="slider"
        data-theme="b" data-track-theme="a">
  <option value="off">Off</option>
  <option value="on" selected>On</option>
</select>

Programmatic Toggle

Set the value with $(el).val(value) then call .slider('refresh') to update the visual toggle to match. Read the current state with .val(). Always refresh after changing the underlying select's value programmatically, or the handle won't move.

jquery-mobile
<select id="power" data-role="slider">
  <option value="off">Off</option>
  <option value="on">On</option>
</select>

<script>
// Turn the switch on programmatically
$("#power").val("on").slider("refresh");
// Read current state
var state = $("#power").val(); // "on" or "off"
</script>
10

Checkboxes & Radios

Checkboxes

A checkbox is a normal <input type=checkbox> wrapped by (or adjacent to) a <label for=id>. jQuery Mobile styles the label as a tappable block. When the label wraps the input, the for attribute is optional. Checked state submits as usual with the form.

jquery-mobile
<label for="agree"><input type="checkbox" id="agree" name="agree"> I agree</label>

<label for="news"><input type="checkbox" id="news" name="news" checked> Newsletter</label>

<!-- Wrap in ui-field-contain for layout -->
<div class="ui-field-contain">
  <label for="agree">I agree to terms</label>
  <input type="checkbox" id="agree">
</div>

Radio Buttons

Group radios by giving them the same name attribute. Wrap the group in a fieldset with data-role=controlgroup (and a <legend>) to cluster them visually with shared corners. Only one radio in a same-named group can be checked at a time.

jquery-mobile
<fieldset data-role="controlgroup">
  <legend>Choose a color:</legend>
  <label for="r"><input type="radio" name="color" id="r" value="red" checked> Red</label>
  <label for="g"><input type="radio" name="color" id="g" value="green"> Green</label>
  <label for="b"><input type="radio" name="color" id="b" value="blue"> Blue</label>
</fieldset>

Horizontal Controlgroups

data-type=horizontal lays out the checkboxes or radios in a single row as a segmented control instead of a vertical stack. This is compact and works well for short labels (S/M/L, Yes/No). Keep labels short so they fit on narrow screens.

jquery-mobile
<fieldset data-role="controlgroup" data-type="horizontal">
  <legend>Size:</legend>
  <label for="s"><input type="radio" name="size" id="s" value="s" checked> S</label>
  <label for="m"><input type="radio" name="size" id="m" value="m"> M</label>
  <label for="l"><input type="radio" name="size" id="l" value="l"> L</label>
</fieldset>

Mini & Theme

data-mini=true shrinks the controls, and data-theme sets the swatch applied when an item is checked/active. Theme the active state to stand out from the page background. These options apply to the whole controlgroup at once.

jquery-mobile
<fieldset data-role="controlgroup" data-mini="true" data-theme="b">
  <label for="a"><input type="checkbox" id="a"> Option A</label>
  <label for="b"><input type="checkbox" id="b"> Option B</label>
</fieldset>

Refresh After Change

After setting a checkbox/radio's checked property in code, call .checkboxradio('refresh') so the enhanced visual matches. If you add or remove inputs inside a controlgroup at runtime, call .controlgroup('refresh') to re-apply the grouped styling.

jquery-mobile
<input type="checkbox" id="c1">

<script>
// Check programmatically and update the visual state
$("#c1").prop("checked", true).checkboxradio("refresh");

// For a controlgroup, refresh the group after adding/removing items
$("#grp").controlgroup("refresh");
</script>
11

Select Menus

Native Select

By default jQuery Mobile shows a custom-styled select, but the underlying OS picker still opens. Set data-native-menu=true (or data-role=none) to use the device's native dropdown entirely — faster and more familiar, but less visually consistent across platforms.

jquery-mobile
<label for="country">Country</label>
<select id="country" data-native-menu="true">
  <option value="us">United States</option>
  <option value="ca">Canada</option>
  <option value="uk">United Kingdom</option>
</select>

<!-- data-role="none" also keeps it fully native -->
<select data-role="none">...</select>

Custom Select Menu

data-native-menu=false opens a jQuery Mobile-styled popup menu instead of the native picker, giving a consistent look on all devices. On a phone it appears as a full-screen dialog with a 'Done' button; on a tablet it appears as a smaller popup near the field.

jquery-mobile
<label for="fruit">Fruit</label>
<select id="fruit" data-native-menu="false">
  <option value="apple">Apple</option>
  <option value="banana">Banana</option>
  <option value="cherry">Cherry</option>
</select>

Placeholder & Multiple

An empty-valued first option acts as a placeholder. data-overlay-theme sets the backdrop color of the custom menu. Adding the multiple attribute turns the custom menu into a checklist dialog where the user can pick several options, shown comma-separated on the button.

jquery-mobile
<label for="color">Color</label>
<select id="color" data-native-menu="false" data-overlay-theme="b">
  <option value="">Choose a color...</option>
  <option value="red">Red</option>
  <option value="green">Green</option>
</select>

<!-- Multiple selection (renders as a checklist dialog) -->
<label for="tags">Tags</label>
<select id="tags" multiple data-native-menu="false">
  <option value="a">A</option>
  <option value="b">B</option>
</select>

Select Theme & Overlay

data-theme styles the select button itself; data-overlay-theme sets the popup/backdrop color; data-divider-theme colors any list-divider separators inside the menu. You can insert <li data-role=list-divider> elements between options to group them visually.

jquery-mobile
<label for="size">Size</label>
<select id="size" data-native-menu="false"
        data-theme="a" data-overlay-theme="b" data-divider-theme="a">
  <option value="s">Small</option>
  <option value="m">Medium</option>
  <li data-role="list-divider">Large sizes</li>
  <option value="l">Large</option>
</select>

Select Events

Listen to the standard 'change' event to react to a selection. After changing the value (or replacing the options) in code, call .selectmenu('refresh') so the button label updates to match the new selection. Rebuild the menu with 'refresh', not re-init.

jquery-mobile
<label for="city">City</label>
<select id="city" data-native-menu="false">
  <option value="ny">New York</option>
  <option value="la">Los Angeles</option>
</select>

<script>
$("#city").on("change", function () {
  console.log("Selected: " + $(this).val());
});
// Update options then refresh
$("#city").val("la").selectmenu("refresh");
</script>
12

Popups

Basic Popup

A popup is a div with data-role=popup. Open it by linking to its id with data-rel=popup. The popup overlays the page centered by default. Add ui-content for padding, and use data-rel=back on a link inside to close it.

jquery-mobile
<a href="#myPopup" data-rel="popup" class="ui-btn">Open popup</a>

<div data-role="popup" id="myPopup" class="ui-content">
  <p>This is a popup.</p>
  <a href="#" class="ui-btn" data-rel="back">Close</a>
</div>

Popup Transitions

Use data-transition on the opening link (or on the popup itself) to choose the animation. pop and fade are the most natural for popups. The same transition set used for pages applies here; the close action reverses the transition automatically.

jquery-mobile
<a href="#p" data-rel="popup" data-transition="pop">Pop</a>
<a href="#p" data-rel="popup" data-transition="fade">Fade</a>
<a href="#p" data-rel="popup" data-transition="slidedown">Slide down</a>

<div data-role="popup" id="p" class="ui-content" data-theme="a">
  <p>Transitioned in.</p>
</div>

Popup Positioning

data-position-to controls where the popup appears: 'origin' (the element that opened it, default), '#someId' (a specific element), or 'window' (centered on screen). You can also pass x/y coordinates when opening programmatically with popup('open', x, y).

jquery-mobile
<!-- Position relative to an element / coordinates -->
<a href="#tip" data-rel="popup" data-position-to="origin">Tip (on the link)</a>
<a href="#tip" data-rel="popup" data-position-to="#target">Tip (on #target)</a>
<a href="#tip" data-rel="popup" data-position-to="window">Centered</a>

<div data-role="popup" id="tip" class="ui-content">
  <p>Positioned popup.</p>
</div>

Popup Menu & Tooltip

A popup can contain any content — a listview becomes a context menu, a paragraph becomes a tooltip. Style the popup with data-theme and the inner content with its own theme. Popups close automatically when the user taps outside (unless data-dismissible=false).

jquery-mobile
<a href="#menu" data-rel="popup" class="ui-btn">Menu</a>
<div data-role="popup" id="menu" data-theme="b">
  <ul data-role="listview" data-inset="true" data-theme="d">
    <li data-role="divider">Actions</li>
    <li><a href="#">Edit</a></li>
    <li><a href="#">Share</a></li>
    <li><a href="#">Delete</a></li>
  </ul>
</div>

Dialog Popup

A popup positioned at the window center with a close button acts as a modal dialog. Add an X button (ui-icon-delete with ui-btn-icon-notext) in the corner. Constrain the width with a max-width style for a true dialog look instead of a full-width sheet.

jquery-mobile
<a href="#dlg" data-rel="popup" data-position-to="window"
   data-transition="pop" class="ui-btn">Open dialog</a>

<div data-role="popup" id="dlg" data-theme="a" class="ui-content"
     style="max-width:400px;">
  <a href="#" data-rel="back" class="ui-btn ui-corner-all ui-icon-delete
     ui-btn-icon-notext ui-btn-right">Close</a>
  <h3>Confirm</h3>
  <p>Are you sure?</p>
  <a href="#" class="ui-btn ui-btn-b" data-rel="back">Yes</a>
  <a href="#" class="ui-btn" data-rel="back">No</a>
</div>

Programmatic Open & Dismissible

Open or close a popup from code with .popup('open'/'close'). data-dismissible=false prevents closing by tapping outside, forcing the user to use a Close button — ideal for required confirmations. You can pass x/y coordinates or a position object when opening.

jquery-mobile
<div data-role="popup" id="p2" data-dismissible="false">
  <p>Cannot close by tapping outside.</p>
  <a href="#" class="ui-btn" data-rel="back">Close</a>
</div>

<script>
// Open programmatically (optionally at coordinates)
$("#p2").popup("open");
$("#p2").popup("open", { x: 100, y: 200 });
// Close programmatically
$("#p2").popup("close");
</script>
13

Panels

Basic Panel

A panel is a div with data-role=panel, placed inside a page (usually before the header). Open it by linking to its id with a button. Use data-rel=close on a link inside to close the panel. Panels are perfect for slide-out navigation menus.

jquery-mobile
<div data-role="page" id="home">
  <div data-role="panel" id="myPanel">
    <h2>Menu</h2>
    <p>Panel content here.</p>
    <a href="#" class="ui-btn" data-rel="close">Close</a>
  </div>

  <div data-role="header">
    <a href="#myPanel" class="ui-btn ui-btn-inline ui-corner-all ui-icon-bars ui-btn-icon-notext">Menu</a>
    <h1>Home</h1>
  </div>
  <div data-role="main" class="ui-content">
    <p>Page content.</p>
  </div>
</div>

Panel Display Modes

data-display controls the open animation: 'reveal' (default) slides the page away to uncover the panel beneath; 'overlay' slides the panel on top of the page; 'push' moves both the panel in and the page over. Overlay is most common for menus.

jquery-mobile
<div data-role="panel" id="p1" data-display="reveal">Reveal</div>
<div data-role="panel" id="p2" data-display="overlay">Overlay</div>
<div data-role="panel" id="p3" data-display="push">Push</div>

<!-- data-display controls how the panel interacts with the page:
     reveal : panel sits under the page, page slides away
     overlay: panel slides over the page (page stays)
     push   : both panel and page slide -->

Panel Position

data-position=left (default) or right sets which side the panel slides in from. You can have both a left and a right panel in the same page. Only one panel can be open at a time; opening a second closes the first.

jquery-mobile
<!-- Left panel (default) -->
<div data-role="panel" id="leftP" data-position="left">Left</div>

<!-- Right panel -->
<div data-role="panel" id="rightP" data-position="right">Right</div>

<a href="#leftP" class="ui-btn">Open left</a>
<a href="#rightP" class="ui-btn">Open right</a>

Dismissible & Swipe

data-dismissible=true (default) closes the panel when the user taps outside it. data-swipe-close=true lets the user swipe in the opposite direction to close it (e.g., swipe right closes a left panel). Both are on by default for overlay panels.

jquery-mobile
<div data-role="panel" id="p"
     data-dismissible="true"
     data-swipe-close="true"
     data-position="left"
     data-display="overlay">
  <p>Tap outside or swipe to close.</p>
</div>

Panel Events

Panels fire panelbeforeopen, panelopen, panelbeforeclose, and panelclose events. Returning false from a 'before' handler cancels the action — useful to confirm before closing. Open/close from code with .panel('open'/'close').

jquery-mobile
<div data-role="panel" id="p">...</div>

<script>
$("#p").on("panelopen", function () {
  console.log("Panel opened");
});
$("#p").on("panelbeforeclose", function () {
  // return false here to prevent closing
  console.log("About to close");
});
$("#p").on("panelclose", function () {
  console.log("Panel closed");
});

// Open / close programmatically
$("#p").panel("open");
$("#p").panel("close");
</script>
14

Collapsibles

Basic Collapsible

A div with data-role=collapsible wraps a heading (h1-h6) as the clickable header and the rest as expandable content. It starts collapsed by default. Clicking the header toggles the content open and closed with a +/- icon.

jquery-mobile
<div data-role="collapsible">
  <h3>Section title</h3>
  <p>Hidden content shown when expanded.</p>
  <p>Click the header to toggle.</p>
</div>

Collapsible Icons & Theme

Customize the indicator with data-collapsed-icon and data-expanded-icon (default plus/minus). data-theme styles the header; data-content-theme styles the expanded content area. data-collapsed=false makes the section start expanded instead of collapsed.

jquery-mobile
<div data-role="collapsible"
     data-collapsed-icon="carat-r"
     data-expanded-icon="carat-d"
     data-theme="b" data-content-theme="a"
     data-collapsed="false">
  <h3>Initially open</h3>
  <p>Custom icons and theme.</p>
</div>

Collapsible Set (Accordion)

A collapsibleset groups collapsibles so only one is open at a time — an accordion. Opening one automatically closes the others. (In 1.4 the attribute is data-role=collapsibleset; the older collapsible-set name still works.) The whole set shares a unified theme.

jquery-mobile
<div data-role="collapsibleset" data-theme="a" data-content-theme="a">
  <div data-role="collapsible">
    <h3>Section 1</h3>
    <p>Only one section open at a time.</p>
  </div>
  <div data-role="collapsible" data-collapsed="false">
    <h3>Section 2 (open by default)</h3>
    <p>Opening this closes Section 1.</p>
  </div>
  <div data-role="collapsible">
    <h3>Section 3</h3>
    <p>Third section.</p>
  </div>
</div>

Pre-expanded & Inset

In a collapsibleset, set data-collapsed=false on the section you want open initially. data-inset=true (default for sets) gives the group rounded corners and margins. Edge-to-edge sets use data-inset=false to span full width.

jquery-mobile
<!-- A set always starts with one open by default; control with data-collapsed -->
<div data-role="collapsibleset" data-inset="true">
  <div data-role="collapsible" data-collapsed="false">
    <h3>Open first</h3>
    <p>Content</p>
  </div>
  <div data-role="collapsible">
    <h3>Closed second</h3>
    <p>Content</p>
  </div>
</div>

Collapsible with Listview

A collapsible can contain any widget, including a listview. This is a great pattern for grouping a long list under a collapsible header. Add data-filter=true to the collapsible to filter the inner listview's items via a search box inside the header area.

jquery-mobile
<div data-role="collapsible" data-filter="true">
  <h3>Contacts</h3>
  <ul data-role="listview">
    <li><a href="#">Alice</a></li>
    <li><a href="#">Bob</a></li>
    <li><a href="#">Carol</a></li>
  </ul>
</div>

Programmatic Expand/Collapse

Control a collapsible from code with .collapsible('expand') and .collapsible('collapse'). Listen to the 'collapse' and 'expand' events to react to user toggling. For a set, expanding one section programmatically collapses the others automatically.

jquery-mobile
<div data-role="collapsible" id="c">
  <h3>Section</h3>
  <p>Content</p>
</div>

<script>
// Expand or collapse from code
$("#c").collapsible("expand");
$("#c").collapsible("collapse");
// Toggle based on current state
$("#c h3").click(); // simplest manual toggle
</script>
15

Tabs

Basic Tabs

A tabs widget is a div with data-role=tabs containing a navbar (the tab links) and content panels whose ids match the link hrefs. The link with ui-btn-active is shown first. Clicking a tab shows its panel and hides the others — no page transition.

jquery-mobile
<div data-role="tabs" id="myTabs">
  <div data-role="navbar">
    <ul>
      <li><a href="#tab1" class="ui-btn-active">One</a></li>
      <li><a href="#tab2">Two</a></li>
      <li><a href="#tab3">Three</a></li>
    </ul>
  </div>
  <div id="tab1" class="ui-body-d ui-content">Content 1</div>
  <div id="tab2" class="ui-body-d ui-content">Content 2</div>
  <div id="tab3" class="ui-body-d ui-content">Content 3</div>
</div>

Tabs with Icons

Add ui-icon-{name} and ui-btn-icon-top classes to the tab links to show icons above the labels, giving an app-like tab bar. The active tab keeps ui-btn-active. Use ui-btn-icon-top so the icon sits above the text in the tab strip.

jquery-mobile
<div data-role="tabs">
  <div data-role="navbar">
    <ul>
      <li><a href="#t1" class="ui-btn-active ui-icon-home ui-btn-icon-top">Home</a></li>
      <li><a href="#t2" class="ui-icon-search ui-btn-icon-top">Search</a></li>
      <li><a href="#t3" class="ui-icon-gear ui-btn-icon-top">Settings</a></li>
    </ul>
  </div>
  <div id="t1" class="ui-content">Home tab</div>
  <div id="t2" class="ui-content">Search tab</div>
  <div id="t3" class="ui-content">Settings tab</div>
</div>

AJAX Tabs

When a tab link's href is a URL (not #id), the tabs widget loads that page via AJAX into the container on activation. The first tab is loaded automatically when the page initializes. This is useful for lazily loading heavy content per tab.

jquery-mobile
<div data-role="tabs">
  <div data-role="navbar">
    <ul>
      <li><a href="ajax-tab1.html" class="ui-btn-active">One</a></li>
      <li><a href="ajax-tab2.html">Two</a></li>
    </ul>
  </div>
  <!-- The first tab's content is loaded into this container -->
  <div class="ui-content" id="ajax-content"></div>
</div>

Tabs Persistence

Tabs don't remember their active state across reloads by default. Use the tabsactivate event (which gives ui.newPanel/ui.oldPanel) plus localStorage to persist the selection. Re-trigger the saved tab's click on load to restore it.

jquery-mobile
<div data-role="tabs" id="t">
  <div data-role="navbar">
    <ul>
      <li><a href="#a" class="ui-btn-active">A</a></li>
      <li><a href="#b">B</a></li>
    </ul>
  </div>
  <div id="a" class="ui-content">A</div>
  <div id="b" class="ui-content">B</div>
</div>

<script>
// Remember the active tab across reloads
var saved = localStorage.getItem("activeTab") || "#a";
$("#t a[href='" + saved + "']").click();
$("#t").on("tabsactivate", function (e, ui) {
  localStorage.setItem("activeTab", "#" + ui.newPanel.attr("id"));
});
</script>

Tab Events

tabsbeforeactivate fires before a tab switch (return false to cancel); tabsactivate fires after. Both give ui.newTab/ui.oldTab (the <a> links) and ui.newPanel/ui.oldPanel (the content divs). Use them to lazy-load content, log analytics, or validate before switching.

jquery-mobile
<div data-role="tabs" id="t">...</div>

<script>
$("#t").on("tabsbeforeactivate", function (e, ui) {
  // ui.newTab, ui.oldTab, ui.newPanel, ui.oldPanel
  // return false to cancel the switch
  console.log("Switching to", ui.newPanel.attr("id"));
});
$("#t").on("tabsactivate", function (e, ui) {
  console.log("Now showing", ui.newPanel.attr("id"));
});
</script>
16

Theming

Theme Swatches (a-e)

jQuery Mobile theming uses lettered 'swatches' (a-e) rather than one color. a is the highest-contrast (dark) and is the default for headers/footers; b is a blue accent; c is the default light page background. Apply a swatch with data-theme on any element.

jquery-mobile
<!-- jQuery Mobile ships with 5 swatches: a, b, c, d, e -->
<!-- a = black (high contrast), b = blue, c = light gray,
     d = medium gray, e = yellow -->

<div data-role="page" data-theme="b">
  <div data-role="header" data-theme="a"><h1>Dark header</h1></div>
  <div data-role="main" class="ui-content">Page body</div>
  <div data-role="footer" data-theme="a"><h4>Dark footer</h4></div>
</div>

Applying Themes

For buttons use the ui-btn-{swatch} class (e.g., ui-btn-b for a blue button). For other elements use data-theme={swatch}. A child inherits its parent's swatch unless you set one explicitly. The default page swatch is 'c' (light gray).

jquery-mobile
<!-- Per element -->
<a href="#" class="ui-btn ui-btn-a">Swatch A button</a>
<a href="#" class="ui-btn ui-btn-b">Swatch B button</a>

<!-- On bars, lists, forms -->
<div data-role="header" data-theme="b">...</div>
<ul data-role="listview" data-theme="c">...</ul>
<input type="text" data-theme="b">

Overlay Theme

data-overlay-theme sets the color of the dimmed backdrop behind a popup, dialog, or custom select menu. Use a dark swatch (a or b) for the overlay so the foreground content stands out. The popup's own data-theme controls the popup box color.

jquery-mobile
<!-- Overlay theme for popups, dialogs, custom selects -->
<div data-role="popup" id="p" data-overlay-theme="b" data-theme="a"
     class="ui-content">
  <p>Dark backdrop, light popup.</p>
</div>

<a href="#p" data-rel="popup" data-transition="pop" class="ui-btn">Open</a>

List & Button Themes

Listviews accept separate themes: data-theme for rows, data-divider-theme for the divider headers, and data-count-theme for the count bubbles. This lets you highlight dividers while keeping rows subtle. The same fine-grained theming applies to buttons and forms.

jquery-mobile
<ul data-role="listview" data-theme="d" data-divider-theme="b"
    data-count-theme="b" data-inset="true">
  <li data-role="list-divider">Group (swatch b)</li>
  <li><a href="#">Item (swatch d) <span class="ui-li-count">5</span></a></li>
</ul>

Custom Swatches

Each swatch is just a set of CSS classes (.ui-bar-{x}, .ui-body-{x}, .ui-btn-up-{x}, etc.). To add a custom swatch 'f', copy these rules and recolor them — or use the ThemeRoller tool to generate a complete custom theme file. Then reference it with data-theme=f.

jquery-mobile
/* Add a custom swatch 'f' by copying the .ui-bar-f, .ui-body-f,
   .ui-btn-up-f, .ui-btn-hover-f, .ui-btn-down-f rules and changing
   the colors. ThemeRoller generates these for you. */
.ui-bar-f { background: #6c2; color: #fff; }
.ui-body-f { background: #efe; color: #030; }
.ui-btn-up-f { background: #6c2; color: #fff; }
.ui-btn-hover-f { background: #5b1; color: #fff; }

<!-- Use it like any built-in swatch -->
<div data-role="header" data-theme="f"><h1>Green header</h1></div>

Theme Inheritance

Elements inherit the nearest ancestor's swatch when they don't set their own. Set a swatch high up (e.g., on the page) to theme everything inside consistently, then override individual elements as needed. Change the global default page theme during mobileinit.

jquery-mobile
<div data-role="page" data-theme="b">
  <!-- Inherits swatch b unless overridden -->
  <div data-role="main" class="ui-content">
    <a href="#" class="ui-btn">Inherits b</a>
    <a href="#" class="ui-btn ui-btn-a">Explicit a</a>
    <a href="#" class="ui-btn" data-theme="a">Explicit a (attr)</a>
  </div>
</div>

<!-- Global default swatch -->
<script>
$(document).on("mobileinit", function () {
  $.mobile.page.prototype.options.theme = "b";
});
</script>
17

Responsive Layout

Grid Layout

Grids are CSS classes, not widgets. ui-grid-a makes a 2-column grid, ui-grid-b is 3 columns, up to ui-grid-d (5 columns). Children get ui-block-a, ui-block-b, ... in order and wrap automatically. Grids are always 100% wide and don't respond to breakpoints on their own.

jquery-mobile
<!-- 2-column grid (ui-grid-a) -->
<div class="ui-grid-a">
  <div class="ui-block-a"><div class="ui-bar">A</div></div>
  <div class="ui-block-b"><div class="ui-bar">B</div></div>
</div>

<!-- 3-column grid (ui-grid-b), 4 = ui-grid-c, 5 = ui-grid-d -->
<div class="ui-grid-b">
  <div class="ui-block-a">A</div>
  <div class="ui-block-b">B</div>
  <div class="ui-block-c">C</div>
</div>

Responsive Grids

jQuery Mobile grids don't have built-in breakpoints, but you can add a custom media query: at narrow widths set the blocks to width:100% and float:none so they stack vertically, and on wider screens let the default columns apply. Add a marker class to scope the rule.

jquery-mobile
<style>
/* Stack grid columns on phones, side-by-side on tablets */
@media (max-width: 40em) {
  .ui-responsive .ui-block-a,
  .ui-responsive .ui-block-b { width: 100%; float: none; }
}
</style>

<div class="ui-grid-a ui-responsive">
  <div class="ui-block-a">Left (stacks on phone)</div>
  <div class="ui-block-b">Right (stacks on phone)</div>
</div>

Reflow Table

A reflow table (data-mode=reflow) reorganizes into a stacked card layout on narrow screens, repeating each column's header as a label next to its value. Add the ui-responsive class so the reflow only kicks in below the breakpoint, keeping a normal table on wide screens.

jquery-mobile
<table data-role="table" data-mode="reflow" class="ui-responsive">
  <thead><tr><th>Name</th><th>Age</th><th>City</th></tr></thead>
  <tbody>
    <tr><td>Alice</td><td>30</td><td>NYC</td></tr>
    <tr><td>Bob</td><td>25</td><td>LA</td></tr>
  </tbody>
</table>

<!-- On narrow screens each cell shows its column header as a label -->

Column Toggle Table

A columntoggle table adds a 'Columns...' button that lets users choose which columns to show. Assign data-priority=1..6 to optional columns (lower = more important, shown at wider breakpoints); columns without a priority always show. The most important columns remain on phones; the rest are tucked into the menu.

jquery-mobile
<table data-role="table" data-mode="columntoggle"
       class="ui-responsive" id="tbl">
  <thead>
    <tr>
      <th data-priority="1">Rank</th>
      <th data-priority="2">Name</th>
      <th>Team</th>           <!-- priority 'persist' (always shown) -->
      <th data-priority="3">Points</th>
      <th data-priority="4">Wins</th>
    </tr>
  </thead>
  <tbody><tr><td>1</td><td>Alice</td><td>Red</td><td>100</td><td>10</td></tr></tbody>
</table>

Breakpoints & Helper Classes

jQuery Mobile has no utility breakpoint classes; you write your own media queries for custom layouts. The built-in 40em (640px) breakpoint only governs when responsive tables (ui-responsive) switch between stacked and tabular modes. For grids and panels, define your own breakpoints with em-based queries.

jquery-mobile
<!-- jQuery Mobile doesn't ship breakpoint classes like Bootstrap,
     but you can combine media queries with jQM structure. -->

<style>
@media (min-width: 45em) { /* tablet+ */
  .split { width: 50%; float: left; box-sizing: border-box; padding: 0 .5em; }
}
</style>

<div class="split">Left panel</div>
<div class="split">Right panel</div>

<!-- ui-responsive class triggers table breakpoints at 40em (640px) -->
18

Touch Events

Tap & Taphold

tap fires on a quick touch (faster and more reliable than click on mobile, which waits ~300ms). taphold fires when the user holds their finger down for ~750ms. Both are normalized to work with mouse and touch, so the same code runs on desktop and mobile.

jquery-mobile
<div id="box" class="ui-bar">Tap or hold me</div>

<script>
$("#box").on("tap", function () {
  $(this).css("background", "yellow");
});
$("#box").on("taphold", function () {
  $(this).css("background", "red");
});
</script>

Swipe & Swipe Direction

swipe fires on any horizontal swipe; swipeleft and swiperight tell you the direction — handy for image carousels or page navigation. These are based on horizontal movement; vertical scrolling is intentionally not treated as a swipe so normal page scrolling still works.

jquery-mobile
<div id="card" class="ui-bar">Swipe me</div>

<script>
$("#card").on("swipe", function () {
  console.log("Swiped in any direction");
});
$("#card").on("swipeleft", function () {
  $(this).text("Swiped left -> next");
});
$("#card").on("swiperight", function () {
  $(this).text("Swiped right -> prev");
});
</script>

Swipe Thresholds

A swipe only registers if it covers at least horizontalDistanceThreshold (default 30px) within durationThreshold (default 1000ms), and stays under verticalDistanceThreshold vertically. Raise the horizontal threshold to require longer swipes; lower it for a more sensitive feel. Set these during mobileinit.

jquery-mobile
<script>
// Globally tune swipe sensitivity (bind before jQM loads)
$(document).on("mobileinit", function () {
  $.event.special.swipe.horizontalDistanceThreshold = 60; // px, default 30
  $.event.special.swipe.durationThreshold = 800;          // ms, default 1000
  $.event.special.swipe.verticalDistanceThreshold = 40;   // px, default 75
});
</script>

<script src="jquery.mobile-1.4.5.min.js"></script>

Virtual Mouse Events

vmouse* events are jQuery Mobile's unified mouse/touch/pointer events — they fire consistently whether the user uses a finger or a mouse. Use vclick instead of click to avoid the mobile 300ms delay. They're the building blocks that tap and swipe are built on.

jquery-mobile
<script>
// vmouse events unify mouse + touch + pointer
$("#el").on("vmousedown", function () { /* finger down / mouse down */ });
$("#el").on("vmouseup",   function () { /* finger up / mouse up   */ });
$("#el").on("vmousemove", function () { /* drag                    */ });
$("#el").on("vmouseover", function () { /* hover-in (best-effort)  */ });
$("#el").on("vmouseout",  function () { /* hover-out (best-effort) */ });
$("#el").on("vclick",     function () { /* tap/click unified       */ });
</script>

Orientation Change

orientationchange fires when the device rotates, with e.orientation equal to 'portrait' or 'landscape'. Wrap layout-dependent code in a short setTimeout because the viewport dimensions update slightly after the event fires. Listen to the 'resize' event as a fallback on devices without a gyroscope.

jquery-mobile
<script>
$(window).on("orientationchange", function (e) {
  // e.orientation is "portrait" or "landscape"
  console.log("Now " + e.orientation);
});

// React after the rotation finishes (layout is settled)
$(window).on("orientationchange", function (e) {
  setTimeout(function () {
    $("body").removeClass("portrait landscape").addClass(e.orientation);
  }, 300);
});
</script>

Scroll & Throttling

scrollstart and scrollstop are jQuery Mobile's throttled scroll events (the browser throttles scroll handlers natively, but these give clear start/stop moments). To prevent scrolling/zooming on an element — e.g., a drawing canvas or a map — bind touchmove and return false.

jquery-mobile
<script>
// scrollstart / scrollstop are throttled for performance
$(document).on("scrollstart", function () {
  $("#hint").hide();
});
$(document).on("scrollstop", function () {
  $("#hint").show();
});

// Silence touch scroll on a specific element
$("#canvas").on("touchmove", false);
</script>
19

Page Events & Lifecycle

Page Initialization Events

pagebeforecreate fires before jQuery Mobile enhances the page's markup — the best place to inject classes or widgets so they get enhanced too. pagecreate fires right after enhancement completes — use it to bind event handlers and initialize plugins. Each fires once per page.

jquery-mobile
<div data-role="page" id="home">
  <div data-role="main" class="ui-content">
    <a href="#second" class="ui-btn">Go to second</a>
  </div>
</div>

<script>
$(document).on("pagebeforecreate", "#home", function () {
  // Before enhancement — good place to add classes/widgets
});
$(document).on("pagecreate", "#home", function () {
  // After enhancement, before show — bind widgets here
  console.log("Home page created");
});
</script>

Page Show & Hide

pagebeforeshow/pageshow fire before/after a page becomes visible; pagebeforehide/pagehide fire before/after it's hidden. 'show' events fire every time the page is displayed (not just once), so they're the right place to refresh dynamic data when returning to a page.

jquery-mobile
<script>
$(document).on("pagebeforeshow", "#home", function () {
  console.log("About to show home");
});
$(document).on("pageshow", "#home", function () {
  console.log("Home shown (transition done)");
});
$(document).on("pagebeforehide", "#home", function () {
  console.log("About to leave home");
});
$(document).on("pagehide", "#home", function () {
  console.log("Home hidden");
});
</script>

Page Before Change

pagebeforechange fires before any navigation and is the place to intercept or redirect it (call preventDefault to cancel). pagechange fires after a successful navigation; pagechangefailed fires if loading the target page errored. These fire for both internal (#id) and AJAX navigations.

jquery-mobile
<script>
$(document).on("pagebeforechange", function (e, data) {
  // data.toPage is the target (URL string or jQuery object)
  // data.options has transition, reverse, etc.
  // return false (or e.preventDefault()) to cancel navigation
  if (typeof data.toPage === "string" && data.toPage.indexOf("block") > -1) {
    e.preventDefault();
    alert("Blocked");
  }
});
$(document).on("pagechange", function (e, data) {
  console.log("Navigation completed");
});
$(document).on("pagechangefailed", function (e, data) {
  console.log("Navigation failed");
});
</script>

Page Container Load

pageload fires when an AJAX-fetched page is successfully inserted into the DOM (data.url and data.page are provided). pageloadfailed fires on a load error — by default jQM shows an error message; returning false from a handler tells jQM you've handled it yourself.

jquery-mobile
<script>
// Fires when a page is loaded via AJAX into the DOM
$(document).on("pageload", function (e, data) {
  console.log("Loaded: " + data.url);
  console.log("Page obj:", data.page);
});
$(document).on("pageloadfailed", function (e, data) {
  // return false to let jQM show its default error message
  console.log("Failed to load: " + data.url);
});
</script>

Binding to Page Events

Bind page events with event delegation on document, filtering by the page's #id selector — this works even for pages pulled in later via AJAX. For programmatic navigation use the pagecontainer widget's 'change' method (the modern replacement for $.mobile.changePage), passing the target and options.

jquery-mobile
<script>
// Delegate by page id — works for AJAX-loaded pages too
$(document).on("pagecreate", "#settings", function () {
  var page = $(this);
  page.find("#save").on("tap", function () {
    alert("Saved settings");
  });
});

// Use the pagecontainer widget (1.4+) for programmatic navigation
$(":mobile-pagecontainer").pagecontainer("change", "#settings", {
  transition: "slide",
  reverse: false
});
</script>

Page Remove & Cleanup

By default jQuery Mobile removes a page from the DOM after you navigate away from it (unless domCache is on). pageremove fires right before removal — clean up intervals, listeners, or plugin instances here. The pagehide event's ui.prevPage gives the just-hidden page's jQuery object for teardown.

jquery-mobile
<script>
// Fires when a page is removed from the DOM (default behavior for
// non-cached pages after navigation away)
$(document).on("pageremove", function (e, ui) {
  console.log("Page removed from DOM:", ui.prevPage);
});

// Clean up resources when a page is hidden for good
$(document).on("pagehide", "#temp", function () {
  clearInterval($(this).data("timer"));
});
</script>

Was this helpful?

Learning path

Learn from scratch

Learn this language from the ground up with structured lessons.