Highlight buildings in the Mapbox Standard Style
This example demonstrates how to highlight individual buildings in the Mapbox Standard Style using the addInteraction method with the built-in buildings featureset.
The code below demonstrates how to:
- Highlight a building on hover using the
highlightfeature state and a pointer cursor to show it is selectable - Persistently select a building on click using the
selectfeature state, clearing any previous selection - Customize the hover and selection colors using the
colorBuildingHighlightandcolorBuildingSelectconfiguration properties - Disable 3D landmarks using the
show3dLandmarksconfiguration property, as this highlighting technique does not work for buildings represented as 3D models
Mapbox Standard Style only
The buildings featureset and colorBuildingHighlight/colorBuildingSelect configuration properties are only available in styles that import the Mapbox Standard Style.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Highlight buildings in the Mapbox Standard Style</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<link href="https://api.mapbox.com/mapbox-gl-js/v3.23.1/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v3.23.1/mapbox-gl.js"></script>
<style>
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
// TO MAKE THE MAP APPEAR YOU MUST
// ADD YOUR ACCESS TOKEN FROM
// https://account.mapbox.com
mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/standard',
center: [-74.0066, 40.7135],
zoom: 15.5,
pitch: 45,
bearing: -17.6,
config: {
// Customize the highlight and select colors for the buildings featureset.
// colorBuildingHighlight controls the hover color (default: blue).
// colorBuildingSelect controls the click/selection color (default: blue).
// show3dLandmarks is set to false, as this highlighting technique does not work for buildings represented as 3D models.
basemap: {
colorBuildingHighlight: '#93C5FD',
colorBuildingSelect: '#1E40AF',
show3dLandmarks: false
}
}
});
let hoveredBuilding = null;
let selectedBuilding = null;
// Show a pointer cursor and highlight the building on hover
map.addInteraction('building-mouseenter', {
type: 'mouseenter',
target: { featuresetId: 'buildings', importId: 'basemap' },
handler: ({ feature }) => {
if (hoveredBuilding) {
map.setFeatureState(hoveredBuilding, { highlight: false });
}
hoveredBuilding = feature;
map.setFeatureState(feature, { highlight: true });
map.getCanvas().style.cursor = 'pointer';
}
});
// Remove the highlight and reset the cursor when the mouse leaves a building.
// Only clear if the leaving feature matches the currently hovered building —
// this prevents stale mouseleave events (which fire per-feature due to
// return false) from clearing a highlight set by a later mouseenter.
map.addInteraction('building-mouseleave', {
type: 'mouseleave',
target: { featuresetId: 'buildings', importId: 'basemap' },
handler: ({ feature }) => {
if (hoveredBuilding && feature.id === hoveredBuilding.id) {
map.setFeatureState(hoveredBuilding, { highlight: false });
hoveredBuilding = null;
map.getCanvas().style.cursor = '';
}
return false;
}
});
// Persistently select a building on click, clearing any previous selection
map.addInteraction('building-click', {
type: 'click',
target: { featuresetId: 'buildings', importId: 'basemap' },
handler: ({ feature }) => {
if (selectedBuilding) {
map.setFeatureState(selectedBuilding, { select: false });
}
selectedBuilding = feature;
map.setFeatureState(feature, { select: true });
}
});
</script>
</body>
</html>
This code snippet will not work as expected until you replace
YOUR_MAPBOX_ACCESS_TOKEN with an access token from your Mapbox account.import React, { useEffect, useRef } from 'react';
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
const MapboxExample = () => {
const mapContainerRef = useRef(null);
const mapRef = useRef(null);
const hoveredBuildingRef = useRef(null);
const selectedBuildingRef = useRef(null);
useEffect(() => {
// TO MAKE THE MAP APPEAR YOU MUST
// ADD YOUR ACCESS TOKEN FROM
// https://account.mapbox.com
mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN';
const map = (mapRef.current = new mapboxgl.Map({
container: mapContainerRef.current,
style: 'mapbox://styles/mapbox/standard',
center: [-74.0066, 40.7135],
zoom: 15.5,
pitch: 45,
bearing: -17.6,
config: {
// Customize the highlight and select colors for the buildings featureset.
// colorBuildingHighlight controls the hover color (default: blue).
// colorBuildingSelect controls the click/selection color (default: blue).
// show3dLandmarks is set to false, as this highlighting technique does not work for buildings represented as 3D models.
basemap: {
colorBuildingHighlight: '#93C5FD',
colorBuildingSelect: '#1E40AF',
show3dLandmarks: false
}
}
}));
// Show a pointer cursor and highlight the building on hover
map.addInteraction('building-mouseenter', {
type: 'mouseenter',
target: { featuresetId: 'buildings', importId: 'basemap' },
handler: ({ feature }) => {
if (hoveredBuildingRef.current) {
map.setFeatureState(hoveredBuildingRef.current, { highlight: false });
}
hoveredBuildingRef.current = feature;
map.setFeatureState(feature, { highlight: true });
map.getCanvas().style.cursor = 'pointer';
}
});
// Remove the highlight and reset the cursor when the mouse leaves a building.
// Only clear if the leaving feature matches the currently hovered building —
// this prevents stale mouseleave events (which fire per-feature due to
// return false) from clearing a highlight set by a later mouseenter.
map.addInteraction('building-mouseleave', {
type: 'mouseleave',
target: { featuresetId: 'buildings', importId: 'basemap' },
handler: ({ feature }) => {
if (
hoveredBuildingRef.current &&
feature.id === hoveredBuildingRef.current.id
) {
map.setFeatureState(hoveredBuildingRef.current, { highlight: false });
hoveredBuildingRef.current = null;
map.getCanvas().style.cursor = '';
}
return false;
}
});
// Persistently select a building on click, clearing any previous selection
map.addInteraction('building-click', {
type: 'click',
target: { featuresetId: 'buildings', importId: 'basemap' },
handler: ({ feature }) => {
if (selectedBuildingRef.current) {
map.setFeatureState(selectedBuildingRef.current, { select: false });
}
selectedBuildingRef.current = feature;
map.setFeatureState(feature, { select: true });
}
});
return () => map.remove();
}, []);
return (
<div ref={mapContainerRef} style={{ width: '100%', height: '100%' }} />
);
};
export default MapboxExample;
This code snippet will not work as expected until you replace
YOUR_MAPBOX_ACCESS_TOKEN with an access token from your Mapbox account.Was this example helpful?