Skip to content

Leaflet.js Popups — Interactive Information Windows

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about Leaflet.js Popups. We cover key concepts, practical examples, and best practices to help you master this topic.

Leaflet.js popups display rich HTML content in information Windows attached to map features, with full customization of styling, positioning, and behavior.

What You'll Learn

By the end of this guide, you will create popups with styled HTML, bind popups to markers and GeoJSON features, customize popup offset and maxWidth, build interactive tooltips, and handle popup events.

Basic Popup

var marker = L.marker([40.7128, -74.0060])
    .addTo(map)
    .bindPopup('<b>New York City</b><br>Population: 8.4M');

Styled Popup

var popup = L.popup({
    maxWidth: 300,
    className: 'custom-popup',
    offset: [0, -20]
}).setContent(
    '<div class="popup-content">' +
        '<h3>Location Details</h3>' +
        '<p>Latitude: 40.7128</p>' +
        '<p>Longitude: -74.0060</p>' +
    '</div>'
);

marker.bindPopup(popup);

Tooltip

marker.bindTooltip('NYC', {
    permanent: false,
    direction: 'top',
    offset: [0, -10],
    opacity: 0.9
});
marker.on('popupopen', function() {
    console.log('Popup opened');
});

marker.on('popupclose', function() {
    console.log('Popup closed');
});

Common Mistakes

1. Popup Overflow

Content wider than maxWidth overflows. Set maxWidth and use CSS word-break for long strings.

2. Missing Close Button

The default popup has a close button. Set closeButton: false in options to remove it, but provide another way to close.

3. Popup Position Not Updated

When the map pans, popups reposition automatically. If the marker moves programmatically, call marker.openPopup() again.

4. HTML Injection

Using user input in popup content without sanitization risks XSS. Sanitize all dynamic content.

5. Too Much Content in Popups

Popup height is limited. For large content, use a scrollable container or link to a panel.

Practice Questions

Q1: What is the difference between popup and tooltip? A: Popup opens on click and has a close button. Tooltip opens on hover and auto-closes.

Q2: How do you set popup width? A: Use maxWidth option (default 300px). Popups do not have a fixed width option.

Q3: How do you auto-open a popup? A: Call marker.openPopup() after binding.

Q4: How do you customize popup appearance? A: Use className option and add CSS for that class.

Q5: How do you close all popups? A: Call map.closePopup().

Challenge: Build a map where each marker shows a popup with an image, description, and a link. Add CSS to make popups look like cards with rounded corners and shadows.

FAQ

Can I add buttons to popups?

Yes. Include HTML button elements and attach event listeners after the popup opens.

How do I change popup animation?

Set options like autoPan: true/false. Popup animations are built-in and not customizable.

Can I have multiple popups open at once?

No. Only one popup opens at a time. Use tooltips for multiple simultaneous info displays.

How do I position a popup at a specific lat/lng?

Create a standalone L.popup and set its latlng property.

Does popup work on mobile?

Yes. Popups respond to tap events on mobile devices.

Try It Yourself

Build a map with styled popups.

<!DOCTYPE html>
<html>
<head>
    <title>Popups Demo</title>
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9/dist/leaflet.css" />
    <script src="https://unpkg.com/leaflet@1.9/dist/leaflet.js"></script>
    <style>
        .custom-popup .leaflet-popup-content-wrapper { border-radius: 8px; box-shadow: 0 3px 12px rgba(0,0,0,0.15); }
        .custom-popup .leaflet-popup-content { margin: 12px 16px; font-family: sans-serif; }
        .custom-popup h3 { margin: 0 0 6px; color: #2a9d8f; }
        .custom-popup p { margin: 2px 0; font-size: 13px; color: #555; }
        .custom-popup .popup-link { display: inline-block; margin-top: 8px; color: #4ecdc4; text-decoration: none; font-weight: bold; }
    </style>
</head>
<body style="font-family:sans-serif;padding:20px;">
<h2>Custom Popups</h2>
<div id="map" style="height:400px;border-radius:8px;"></div>
<script>
var map = L.map('map').setView([40.7128, -74.0060], 12);

L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '&copy; OSM'
}).addTo(map);

var locations = [
    { lat: 40.7128, lng: -74.0060, name: 'Financial District', desc: 'Home to Wall Street and the New York Stock Exchange.' },
    { lat: 40.7580, lng: -73.9855, name: 'Times Square', desc: 'Iconic commercial and entertainment hub.' },
    { lat: 40.7484, lng: -73.9856, name: 'Empire State Building', desc: '102-story landmark skyscraper.' },
    { lat: 40.7614, lng: -73.9776, name: 'MoMA', desc: 'Museum of Modern Art, world-renowned art collection.' }
];

locations.forEach(function(loc) {
    var marker = L.marker([loc.lat, loc.lng]).addTo(map);
    marker.bindPopup(
        '<h3>' + loc.name + '</h3>' +
        '<p>' + loc.desc + '</p>' +
        '<a class="popup-link" href="https://en.wikipedia.org/wiki/' + encodeURIComponent(loc.name) + '" target="_blank">Learn More</a>',
        { className: 'custom-popup', maxWidth: 280 }
    );
});
</script>
</body>
</html>

What's Next

Add measurement tools.

Measurement — Measuring distances and areas. Offline — Offline map support.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro