MapBox GL JS Marker with title

by amay077

HTML

<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v1.8.0/mapbox-gl.js"></script>
<link rel="stylesheet" href="https://api.tiles.mapbox.com/mapbox-gl-js/v1.8.0/mapbox-gl.css">
<div id='map'></div>

<template id="marker">
  <div class="marker-container">
    <span id="title" class="marker-title"></span>
    <img id="marker-icon" src="https://img.icons8.com/ios-filled/40/0000FF/marker.png">
  </div>>
</template>

CSS

body {
  margin: 0;
  padding: 0;
}

#map {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
}

.marker-container {
  display: flex; 
  flex-direction: column; 
  align-items: center; 
  cursor: pointer;
}

.marker-title {
  max-width: 100px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.marker-icon {
  height: 30px; 
  width: auto; 
  background-size: cover;
}

.mapboxgl-popup {
  max-width: 200px;
}

.mapboxgl-popup-content {
  text-align: center;
  font-family: 'Open Sans', sans-serif;
}

JavaScript

const geojson = {
  type: 'FeatureCollection',
  features: [{
    type: 'Feature',
    geometry: {
    type: 'Point',
      coordinates: [-77.032, 38.913]
    },
    properties: {
      title: 'Mapbox',
      description: 'Washington, D.C.'
    }
  },
  {
    type: 'Feature',
    geometry: {
      type: 'Point',
      coordinates: [-122.414, 37.776]
    },
    properties: {
      title: 'Mapbox',
      description: 'San Francisco, California'
    }
  }]
};

const map = new mapboxgl.Map({
  container: 'map',
  center: [-96, 37.8],
  zoom: 3,
  style: {
    "version": 8,
    "sources": {
      "OSM": {
        "type": "raster",
        "tiles": ['https://a.tile.openstreetmap.org/{z}/{x}/{y}.png'],
        "tileSize": 256
      }
    },
    "layers": [{
      "id": "OSM",
      "type": "raster",
      "source": "OSM"
    }]
  }
});

geojson.features.forEach(marker => {

  // Create element for marker from template
  const template = document.getElementById('marker');
  const clone = document.importNode(template.content, true);
  const el = clone.firstElementChild;
  
  clone.getElementById('title').innerHTML = marker.properties.description;
  
  new mapboxgl.Marker(el, { anchor: 'bottom' })
    .setLngLat(marker.geometry.coordinates)
    .setPopup(new mapboxgl.Popup({ offset: 60, anchor: 'bottom' }) // add popups
    .setHTML('<h3>' + marker.properties.title + '</h3><p>' + marker.properties.description + '</p>'))
    .addTo(map);
});