Blog Web & Frontend
WEB DEVELOPMENT

Create a Mobile-Responsive Web Map with Leaflet.js

Building a lightweight, mobile-friendly interactive map with Leaflet.js — markers, layers, and the responsive touches that make it usable on a phone, not just a desktop.

Mar 24, 2023

Leaflet is the map library we default to when a project needs pins on a map and does not need the full weight of Google Maps or Mapbox GL. It is small (around 40KB gzipped), needs no API key if you are using OpenStreetMap tiles, and behaves well on mobile out of the box as long as you do not fight its defaults.

Initializing the Map and Tile Layer

A Leaflet map needs a container element with a defined height, a center coordinate, a zoom level, and a tile layer. OpenStreetMap's tile server is the easiest way to start since it needs no API key, though you should move to a paid tile provider (MapTiler, Mapbox, Stadia) before pushing meaningful production traffic — the free OSM tile servers rate-limit and expect proper attribution.

Markers and Popups

Markers attach to specific coordinates, and .bindPopup() attaches an info window that opens on click — both are one-liners once the map instance exists. If you need to toggle groups of pins on and off, attach markers to an L.layerGroup() instead of adding them to the map directly.

html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
  <style>
    html, body { margin: 0; height: 100%; }
    #map { width: 100%; height: 100vh; }
  </style>
</head>
<body>
  <div id="map"></div>

  <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
  <script>
    const map = L.map('map', { tap: true }).setView([21.1702, 72.8311], 13);

    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      maxZoom: 19,
      attribution: '© OpenStreetMap contributors'
    }).addTo(map);

    const marker = L.marker([21.1702, 72.8311]).addTo(map);
    marker.bindPopup('<b>Xtreme Thoughts</b><br>Surat office.');

    window.addEventListener('resize', () => map.invalidateSize());
  </script>
</body>
</html>

Making It Actually Work on Mobile

Leaflet handles pinch-to-zoom and drag panning natively, but three things trip people up. The map container needs an explicit height in CSS — a map inside a flex or grid container with no defined height renders as a gray box. The viewport meta tag needs width=device-width and an initial scale, or mobile browsers render the page (and the map) zoomed out to fit an assumed desktop width. And if the container is hidden or resized after the map loads — a tab switch, an accordion panel opening — you need to call map.invalidateSize() or Leaflet keeps rendering tiles sized for the old container.

The default zoom control is already touch-friendly, but if the map sits inside a scrollable page, consider disabling single-finger drag-to-pan or scroll-wheel zoom on the map itself so visitors can scroll past it without getting stuck interacting with it instead.

  • Explicit height on the map container via CSS, not an assumed default
  • A correct viewport meta tag: width=device-width, initial-scale=1.0
  • map.invalidateSize() after any container resize or visibility change
  • Two-finger drag or a tap-to-activate prompt if the map sits inside a scrollable page
  • Touch-sized popup close buttons and marker hit areas

The single most common "Leaflet map is blank or gray" bug is a container with no height. Leaflet renders into whatever height the CSS gives its div, and unlike an image element, an empty div collapses to zero pixels unless you set a height explicitly.

Wrapping Up

Leaflet gets you a fully interactive, touch-ready map with maybe twenty lines of code. Almost every problem people report with it on mobile traces back to CSS sizing or the viewport meta tag rather than the library itself.

Leaflet.js Maps Responsive

More from the blog

View all articles

Read something that fits your problem?

Tell us what you're building. We'll come back with an honest, scoped recommendation — not a sales pitch.

Start a Project