Henry A. Kissinger once told:
The absence of alternatives clears the mind marvelously.
So why are we always looking for the opposite? Last few years Google maps became a standard in an online map industry. Unfortunately, bigger user base don’t always translate to a better service; precisely that happened to Google maps. Personally, this is not a problem for desktop computers, but a situation is not that good when viewed from the mobile perspective.
Somewhere along the way came Leaflet framework, a modern open-source JavaScript library for mobile-friendly interactive maps. It is developed by Vladimir Agafonkin with a team of dedicated contributors. Weighing just about 31 KB of JS, it has all the features most developers ever need for online maps. I will try to show you how to implement this framework into any jQuery Mobile project.

Note: If this tutorial was helpful, need further clarification, something is not working or do you have a request for another Ionic post? Furthermore, if you don't like something about this blog, if something is bugging you, don't like how I'm doing stuff here, again leave me a comment below. I'm here to help you, I expect the same from you. Feel free to comment below, subscribe to my blog, mail me to dragan.gaic@gmail.com, or follow and mention me on twitter (@gajotres). Thanks and have a nice day!

PS. If you want my help, if possible (even if it takes you some time to do that), create a working example I can play with. Use Plunker for AngularJS based questions or jsFiddle for jQuery/jQuery Mobile based questions.


Table of Contents

Page preparation

Before we create our first example, we need to make some modifications to our jQuery Mobile page. For those of you who don’t know, any map implementation including Leaflet requires enough space to display a map. Usually, this is not a problem, then again this is jQuery Mobile.
Typical jQuery Mobile page consists of immediate children <div>’s with data-roles of header, content, and footer. Content div will never cover all available space, left by header and footer. We can fix it with a little bit of CSS:
.ui-content {
    position: absolute;
    top: 40px;
    right: 0;
    bottom: 40px;
    left: 0;
    padding: 0 !important;
Replace 40px with 0 if your page don’t have header or footer. Don’t forget to included !important with padding, it can’t be removed without this override.
This is a most important step of this tutorial, CSS definitions found in an official tutorial will not work with jQuery Mobile. Next step, viewport meta tag must be included in the head section or our HTML page:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
One last thing, our map container should be set to 100% height:
#map {
    height: 100%;

Initializing the map

This is where Leaflet shines, it can be initialized during any jQuery Mobile page event, which is great. For those of you who don’t know, Google maps initialization will work only during the pageshow event. That looks non-native-like, sometimes with a lot of flickerings.
And here’s the final result:
jQuery Mobile and Leaflet integration
Note: When browser asks you for your location click Allow.


<!DOCTYPE html>
        <title>jQM Complex Demo</title>
        <meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
        <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0; user-scalable=no; target-densityDpi=device-dpi"/>
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.css" />
        <link rel="stylesheet" href="http://leafletjs.com/dist/leaflet.css" />
        <!--<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>-->
        <script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"></script>
        <script src="http://leafletjs.com/dist/leaflet.js"></script>
        <div data-role="page" id="index">
            <div data-theme="b" data-role="header">
                <h1>Index page</h1>
            <div data-role="content">
                <div id="map">1</div>


$(document).on('pageinit', '#index', function(){  
    var map = L.map('map');
    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
        maxZoom: 16,
        attribution: 'Example made by <a href="http://www.gajotres.net">Gajotres</a>'
    map.on('locationfound', onLocationFound);
    map.on('locationerror', onLocationError);
    map.locate({setView: true, maxZoom: 18});    

function onLocationFound(e) {
    var radius = e.accuracy / 2;
    .bindPopup("You are within " + radius + " meters from this point").openPopup();
    L.circle(e.latlng, radius).addTo(map);

function onLocationError(e) {


.ui-content {
    position: absolute;
    top: 40px;
    right: 0;
    bottom: 0;
    left: 0;
    padding: 0 !important;

#map {
    height: 100%;

Who Am I?

Between working as a senior Java developer in one of the largest insurance companies in the world and traveling, in my free time, I work as a professional mobile development adviser. I'm also a major jQuery Mobile supporter back at StackOverflow and a forum moderator at the official Ionic Framework forum.

  • Ageara

    Thanks for the post. I had to change the semicolons separating the content properties in the viewport meta tag to commas.

  • Gorkem
  • David


    Using your code works great, but if I add a footer after content the footer is not in the correct position.
    Have you tried this situation?


    • Just add data-position=”fixed” attribute into your footer div.

  • Alice Klein

    I’m new using leaflet and jquery. I do not understand where the javascript or css are referenced /included?
    Hope you can tell me where to look.

  • Leonel

    Very useful! Thanks!!!!!!