Skip to content

Markers and Popups

This page documents the Markers and Popups UI components in Mapbox GL JS, which allow developers to add interactive points of interest and information windows to maps. Unlike map layers which are rendered directly in WebGL, markers and popups are implemented as HTML elements positioned over the map canvas.

For information about other UI components like navigation controls, scale controls, etc., see Controls. For details on interaction handling, see Interaction and Events.

Overview and Architecture

Markers and popups are part of the UI components system in Mapbox GL JS. They provide a way to add interactive elements to the map that remain tied to specific geographic coordinates even as the map is panned, zoomed, or rotated.

SVG
100%

Marker System

Markers are HTML elements that visually mark specific geographic locations on the map. They can be simple default markers or customized HTML elements.

Creating and Positioning Markers

Markers are created using the Marker class constructor and positioned using setLngLat():

// Create a default marker
const marker = new mapboxgl.Marker()
    .setLngLat([longitude, latitude])
    .addTo(map);

When a marker is added to the map, it creates a DOM element with the class mapboxgl-marker. The marker's position is maintained using CSS transforms as the map moves.

DOMMapMarkerDeveloperDOMMapMarkerDeveloper"new Marker()""setLngLat([lng, lat])""addTo(map)""Register with map""Create DOM element""Update position (on map move)""Update transform"

Marker Styling and Customization

Markers can be customized by:

  1. Passing an HTML element to the constructor
  2. Setting properties like color, rotation, and scale
  3. Making them draggable for user interaction
// Create a custom HTML element
const el = document.createElement('div');
el.className = 'custom-marker';

// Create a marker with the custom element
const marker = new mapboxgl.Marker({
    element: el,
    color: '#FF0000',
    scale: 1.5,
    draggable: true,
    rotation: 45
}).setLngLat([longitude, latitude])
  .addTo(map);

The CSS for markers defines their basic appearance with absolute positioning and opacity transitions:

.mapboxgl-marker {
    position: absolute;
    top: 0;
    left: 0;
    will-change: transform;
    opacity: 1;
    transition: opacity 0.2s;
}

Popups are information windows that display content over the map. They can be standalone or attached to markers.

Creating and Using Popups

Popups are created with the Popup class and can display HTML content:

// Create a standalone popup
const popup = new mapboxgl.Popup()
    .setLngLat([longitude, latitude])
    .setHTML('<h3>Hello World!</h3>')
    .addTo(map);

The example from the debug page shows creating a popup on map click:

map.on('click', function(e) {
    if (e.originalEvent.shiftKey) return;
    (new mapboxgl.Popup())
        .setLngLat(map.unproject(e.point))
        .setHTML("<h1>Hello World!</h1>")
        .addTo(map);
});

A popup consists of several HTML elements with specific classes:

SVG
100%

The CSS for these components defines their appearance:

ComponentCSS ClassPurpose
Container.mapboxgl-popupMain popup container with positioning
Tip.mapboxgl-popup-tipTriangular pointer indicating anchor point
Content.mapboxgl-popup-contentContainer for the popup content
Close Button.mapboxgl-popup-close-buttonButton to close the popup

Popups can be anchored to different positions relative to their geographic coordinates. The anchor determines how the popup is positioned and which direction the tip points.

SVG
100%

The anchor position is set using the setAnchor() method:

popup.setAnchor('top-left');

The CSS for different anchors changes the flex direction and tip styling:

.mapboxgl-popup-anchor-top,
.mapboxgl-popup-anchor-top-left,
.mapboxgl-popup-anchor-top-right {
    flex-direction: column;
}

.mapboxgl-popup-anchor-bottom,
.mapboxgl-popup-anchor-bottom-left,
.mapboxgl-popup-anchor-bottom-right {
    flex-direction: column-reverse;
}

Integration between Markers and Popups

Popups can be attached to markers to create interactive points of interest:

// Create a marker with an attached popup
const marker = new mapboxgl.Marker()
    .setLngLat([longitude, latitude])
    .setPopup(new mapboxgl.Popup().setHTML('<h3>Hello World!</h3>'))
    .addTo(map);

// The popup will appear when the marker is clicked

Common Interaction Patterns

MapPopupMarkerUserMapPopupMarkerUser"Click""Show popup""Add to map""Click close button""Remove from map""Click elsewhere""Close popup""Remove from map"

Popups can be configured to track the mouse pointer, useful for creating hover effects:

const popup = new mapboxgl.Popup({
    closeButton: false,
    closeOnClick: false,
    trackPointer: true
});

The CSS includes specific classes for tracking pointer behavior:

.mapboxgl-popup-track-pointer {
    display: none;
}

.mapboxgl-map:hover .mapboxgl-popup-track-pointer {
    display: flex;
}

.mapboxgl-map:active .mapboxgl-popup-track-pointer {
    display: none;
}

Advanced Customization

Custom Styling

Both markers and popups can be styled with custom CSS by targeting their class names:

/* Custom popup styling */
.mapboxgl-popup-content {
    background-color: #3e3e3e;
    color: white;
    border-radius: 5px;
    padding: 15px;
}

.mapboxgl-popup-tip {
    border-top-color: #3e3e3e; /* For bottom-anchored popups */
}

/* Custom marker styling */
.custom-marker {
    background-image: url('marker.png');
    background-size: cover;
    width: 30px;
    height: 30px;
    cursor: pointer;
}

Accessibility Considerations

When creating markers and popups, consider accessibility by:

  1. Using proper semantic HTML within popups
  2. Adding ARIA attributes to custom marker elements
  3. Ensuring sufficient color contrast for text content
  4. Providing keyboard navigation support

Performance Considerations

For maps with many markers:

  1. Consider using symbol layers from data sources for better performance
  2. Add and remove markers dynamically based on the viewport
  3. Implement clustering for dense marker collections
  4. Limit the number of simultaneously open popups

Events

Both markers and popups emit events that can be handled:

// Marker events
marker.on('dragstart', () => console.log('Started dragging'));
marker.on('dragend', () => console.log('Finished dragging'));

// Popup events
popup.on('open', () => console.log('Popup opened'));
popup.on('close', () => console.log('Popup closed'));

For more detailed information about event handling, see Interaction and Events.

Reference

Marker Options

OptionTypeDefaultDescription
elementHTMLElementDefault markerCustom HTML element to use as the marker
colorstring'#3FB1CE'Color of the default marker
scalenumber1Scale factor for the marker
draggablebooleanfalseWhether the marker can be dragged
rotationnumber0Rotation angle of the marker in degrees
anchorstring'center'Position of the marker relative to coordinates
offsetPointLike[0, 0]Pixel offset from the marker's anchor position
OptionTypeDefaultDescription
closeButtonbooleantrueWhether to show the close button
closeOnClickbooleantrueWhether to close the popup when the map is clicked
closeOnMovebooleanfalseWhether to close the popup when the map moves
anchorstring'bottom'Position of the popup relative to coordinates
offsetnumber, PointLike, Object0Pixel offset from the popup's anchor position
classNamestring''Additional class to add to the popup
maxWidthstring'240px'Maximum width of the popup
trackPointerbooleanfalseWhether the popup should track the mouse pointer
focusAfterOpenbooleantrueWhether the popup should receive focus when opened