Skip to content

Popups and Tooltips

This document covers the popup and tooltip overlay system in Leaflet. Popups and tooltips are HTML-based overlays that display information above map layers at specific geographic positions. Both extend from a common DivOverlay base class and can be bound to layers or displayed standalone.

For information about other overlay types such as image overlays, see Tile Layers and Grid System. For information about layer groups and feature groups that can also have bound popups/tooltips, see Layer Groups and Feature Groups.

Architecture Overview

The overlay system is built on a three-tier class hierarchy where DivOverlay provides the foundation for both Popup and Tooltip.

Class Hierarchy

SVG
100%

DivOverlay Base Class

The DivOverlay class provides shared functionality for all HTML-based overlays positioned at geographic coordinates.

FeatureDescriptionImplementation
Content ManagementSupports string, HTMLElement, or function contentsrc/layer/DivOverlay.js158-171
Position BindingLinks overlay to LatLng coordinatesrc/layer/DivOverlay.js141-156
Source TrackingReferences the layer that opened the overlaysrc/layer/DivOverlay.js45-56
Interactive ModeOptional event listening on overlay containersrc/layer/DivOverlay.js120-123
Pane ManagementControls z-index via map pane systemsrc/layer/DivOverlay.js34-36
FeatureGroup SupportAutomatically selects visible layer from groupsrc/layer/DivOverlay.js232-269

Key Methods:

The Popup class implements modal-style overlays with automatic closing behavior and viewport management.

Configuration Options

SVG
100%

DOM Structure

The popup creates a layered HTML structure with content wrapper, tip (arrow), and optional close button.

SVG
100%

Auto-Pan Mechanism

When autoPan: true, the map automatically pans to ensure the popup is fully visible within the viewport.

SVG
100%

Calculation Logic:

  1. Convert popup position to container point src/layer/Popup.js298
  2. Calculate overflow in each direction (right, left, bottom, top) src/layer/Popup.js306-317
  3. Apply padding offsets src/layer/Popup.js299-302
  4. Pan by calculated deltas if non-zero src/layer/Popup.js323-332

Auto-Close Behavior

Popups implement singleton-like behavior where opening a new popup automatically closes the previous one.

ScenarioBehaviorImplementation
Open new popup with autoClose: trueCloses map._popup if it existssrc/layer/Popup.js138-147
Open popup with autoClose: falseMultiple popups can coexistsrc/layer/Popup.js141
Click map with closePopupOnClick: truePopup closes via preclick eventsrc/layer/Popup.js193-205
Press ESC key with closeOnEscapeKey: truePopup closes (handled by map)src/layer/Popup.js114-117

Content Tracking with ResizeObserver

Popups use ResizeObserver to detect content size changes (e.g., images loading) and automatically reposition.

SVG
100%

Tooltip Class

The Tooltip class implements lightweight, non-modal overlays with directional positioning and pointer-following capabilities.

Configuration Options

OptionDefaultDescription
direction'auto'Placement: 'right', 'left', 'top', 'bottom', 'center', 'auto'
permanentfalseShow permanently instead of on hover
stickyfalseFollow pointer instead of fixed position
opacity0.9Container opacity
offset[0, 0]Position offset in pixels
pane'tooltipPane'Map pane for rendering

Directional Positioning

Tooltips calculate position based on direction, automatically switching to 'left' or 'right' when direction is 'auto'.

SVG
100%

The positioning algorithm:

  1. Determine direction (auto or explicit) src/layer/Tooltip.js165-188
  2. Calculate offset from tooltip dimensions src/layer/Tooltip.js165-188
  3. Apply CSS class for direction styling src/layer/Tooltip.js192-199
  4. Set final DOM position src/layer/Tooltip.js199

Sticky Mode

When sticky: true, the tooltip follows the pointer rather than being anchored to a fixed position.

SVG
100%

Permanent vs. Temporary Tooltips

Tooltips can be permanent (always visible) or temporary (shown on hover/focus).

ModeTriggersEvent Listeners
Permanent (permanent: true)Shown immediately on layer addadd, remove, move events
Temporary (default)User interactionpointerover, pointerout, click, focus, blur, move, remove

Temporary tooltip event binding:

pointerover -> _openTooltip()
pointerout -> closeTooltip()
click -> _openTooltip()
focus -> _openTooltip() (via _addFocusListeners)
blur -> closeTooltip()

Accessibility Features

Tooltips implement ARIA attributes for screen reader accessibility:

  1. Role attribute: Container has role="tooltip" src/layer/Tooltip.js146
  2. Unique ID: Each tooltip gets id="leaflet-tooltip-{stamp}" src/layer/Tooltip.js147
  3. aria-describedby: Bound layer elements reference tooltip ID src/layer/Tooltip.js414-417

Layer Binding API

Both popups and tooltips extend the Layer class with binding methods that attach overlays to layers and manage interaction events.

Binding Methods

SVG
100%

Event Handler Registration

When bindPopup() or bindTooltip() is called, the layer registers event handlers to manage overlay visibility.

Popup Event Handlers:

click -> _openPopup()
keypress -> _onKeyPress() (opens on Enter key)
remove -> closePopup()
move -> _movePopup()

Tooltip Event Handlers (non-permanent):

pointerover -> _openTooltip()
pointerout -> closeTooltip()
click -> _openTooltip()
focus -> _openTooltip() (via _addFocusListeners)
blur -> closeTooltip()
pointermove -> _moveTooltip() (if sticky: true)

Function-Based Content

Both overlays support function content that receives the source layer as an argument, enabling dynamic content based on layer properties.

// Example from test suite
marker.description = 'I am a marker.';
marker.bindPopup(layer => layer.description);

// FeatureGroup with multiple layers
const group = new FeatureGroup([marker1, marker2]);
group.bindTooltip(layer => \`Tooltip: ${layer.options.description}\`);

Implementation:

Positioning and Anchoring

Overlays are positioned relative to their geographic coordinates with optional offsets and anchor points from the source layer.

Position Calculation Flow

SVG
100%

Anchor Points

Layers provide anchor points that specify where the overlay should be positioned relative to the layer's visual representation.

Layer TypeAnchor MethodPurpose
Marker_getPopupAnchor()Position at icon's popup anchor point
Marker_getTooltipAnchor()Position at icon's tooltip anchor point
Path(no anchor method)Uses default [0, 0] anchor

Default Behavior:

Offset System

Both overlays support pixel offsets to fine-tune positioning:

Event System

Popups and tooltips fire events on both the map and the source layer when opened or closed.

Event Flow Diagram

SVG
100%

Event Types

EventFired OnPayloadWhen
popupopenMap, Layer{popup: Popup}Popup added to map
popupcloseMap, Layer{popup: Popup}Popup removed from map
autopanstartMap{...}Auto-pan begins
tooltipopenMap, Layer{tooltip: Tooltip}Tooltip added to map
tooltipcloseMap, Layer{tooltip: Tooltip}Tooltip removed from map
contentupdateDivOverlay{...}Content updated

Event Propagation

Layer events propagate up through event parents:

  1. Overlay fires event on itself
  2. Event fires on source layer with propagate: true src/layer/Popup.js163 src/layer/Tooltip.js106
  3. Event bubbles to layer's event parent (if set)
  4. Map also receives event directly src/layer/Popup.js156 src/layer/Tooltip.js97

Map API Methods

The LeafletMap class provides convenience methods for working with popups and tooltips.

Map Extensions

SVG
100%

Implementation:

Usage Patterns

Standalone Overlays

Create and position overlays independently of layers:

// Popup with position and options
const popup = new Popup(latlng, {content: 'Hello world!'})
    .openOn(map);

// Tooltip with fluent API
const tooltip = new Tooltip()
    .setLatLng(latlng)
    .setContent('Tooltip text')
    .addTo(map);

Bound to Markers

The most common pattern binds overlays to markers with automatic positioning:

// Bind popup to marker
marker.bindPopup('Popup content').openPopup();

// Bind tooltip with options
marker.bindTooltip('Tooltip text', {
    direction: 'top',
    permanent: true
});

Toggle behavior: Clicking a marker with bound popup toggles it open/closed src/layer/Popup.js478-498

Bound to Vector Layers

Paths (polylines, polygons) support popups/tooltips that position at the click point or path center:

const polygon = new Polygon(coordinates);
polygon.bindPopup('Polygon info');
polygon.bindTooltip('Hover tooltip');

Vector layers do not toggle popups on click - they open the popup and prevent map click propagation src/layer/Popup.js282-299

Bound to FeatureGroups

FeatureGroups share a single popup/tooltip across multiple layers, with dynamic content based on the interacted layer:

const group = new FeatureGroup([marker1, marker2]);
group.bindTooltip(layer => \`Info for ${layer.options.name}\`);

When a layer in the group is clicked/hovered, the overlay's _source is set to that specific layer src/layer/DivOverlay.js236-248

Preventing Map Drag Interference

Tooltips check if map is dragging before opening to avoid flickering when pointer moves faster than map:

// Internal logic in _openTooltip
if (this._map.dragging?.moving()) {
    // Defer opening until moveend if layer just added
    if (e.type === 'add' && !this._moveEndOpensTooltip) {
        this._moveEndOpensTooltip = true;
        this._map.once('moveend', () => {
            this._moveEndOpensTooltip = false;
            this._openTooltip(e);
        });
    }
    return;
}

Dynamic Content Updates

Content can be updated after binding using setContent() or by rebinding:

// Update content on existing popup
layer.setPopupContent('New content');

// Update via popup instance
const popup = layer.getPopup();
popup.setContent('Updated');

// Force re-render
popup.update();

The update() method recalculates content, layout, and position src/layer/DivOverlay.js181-193