Skip to content

Markers and Icons

This document covers Leaflet's marker and icon system, which enables placement of interactive, clickable markers on maps. Markers represent geographical points using customizable icons and support user interaction including dragging, clicking, and keyboard navigation. For information about vector shapes and paths, see Vector Layers. For popup and tooltip overlays, see Popups and Tooltips.

Architecture Overview

The marker system consists of two main components: the Marker class that handles positioning and interaction, and the Icon system that defines visual appearance. Markers extend the base Layer class and integrate with Leaflet's event system and map panes for rendering.

Marker and Icon Class Hierarchy

SVG
100%

Marker Class Implementation

The Marker class extends Layer and manages geographical positioning, DOM element lifecycle, and user interaction. Markers are initialized with a LatLng position and optionally an Icon instance.

Marker Options and Configuration

OptionTypeDefaultDescription
iconIconDefaultIcon()Icon instance for rendering
draggableBooleanfalseEnable marker dragging
keyboardBooleantrueEnable keyboard accessibility
titleString''Browser tooltip text
altString'Marker'Alt text for icon image
zIndexOffsetNumber0Z-index offset for stacking
opacityNumber1.0Marker opacity
riseOnHoverBooleanfalseBring to front on hover

Icon System Architecture

The icon system uses a plugin pattern where different icon types implement the same interface. The base Icon class defines the creation contract, while concrete implementations handle specific rendering approaches.

Icon Creation Flow

SVG
100%

Icon Types

Icon (Image-based Icons) The base Icon class creates <img> elements with configurable URLs, sizes, and anchor points. It supports retina displays and shadow images.

// Icon configuration options
const customIcon = new Icon({
    iconUrl: 'marker-icon.png',
    iconRetinaUrl: 'marker-icon-2x.png',
    iconSize: [25, 41],
    iconAnchor: [12, 41],
    popupAnchor: [1, -34],
    shadowUrl: 'marker-shadow.png',
    shadowSize: [41, 41]
});

DefaultIcon (Default Blue Markers) DefaultIcon extends Icon with predefined blue marker images and automatic path detection. It attempts to locate icon assets relative to the Leaflet CSS file.

DivIcon (HTML-based Icons)
DivIcon creates <div> elements instead of images, allowing custom HTML content and CSS styling. It ignores image-related options and never creates shadows.

Marker Lifecycle and Positioning

Markers follow the standard Layer lifecycle with specialized handling for icon creation, positioning, and z-index management based on latitude.

Marker Lifecycle Flow

SVG
100%

Positioning and Z-Index Management

Markers automatically calculate z-index values based on their latitude to ensure proper visual stacking. Southern markers appear above northern ones.

// Z-index calculation in _setPos()
this._zIndex = pos.y + this.options.zIndexOffset;

Interaction and Events

Markers support comprehensive interaction including dragging, keyboard navigation, and standard pointer events. The interaction system integrates with Leaflet's event propagation mechanism.

Marker Event Flow

SVG
100%

Marker Events

EventDescriptionEvent Data
moveFired when marker position changes{oldLatLng, latlng}
clickStandard pointer clickStandard DOM event data
drag*Dragging eventsPosition and drag state data

Dragging System

Marker dragging is implemented through the MarkerDrag class (extending Handler), which handles pointer events, auto-panning, and position updates. The MarkerDrag handler is initialized in the marker's _initInteraction() method and uses the Draggable utility for low-level drag handling.

MarkerDrag Handler Flow

SVG
100%

Integration with Map Panes

Markers use the map's pane system for DOM organization, with separate panes for icons and shadows to ensure proper rendering order.

Marker Pane Usage

SVG
100%

Accessibility Features

Markers include comprehensive accessibility support including keyboard navigation, ARIA attributes, and screen reader compatibility.

// Accessibility setup in _initIcon()
if (options.keyboard) {
    icon.tabIndex = '0';
    icon.setAttribute('role', 'button');
}