Leaflet.js Popups — Interactive Information Windows
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
});
Popup Events
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
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: '© 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