Responsive CSS Hotspots

Hotspot links and buttons on a responsive image. With animated "pulse" effect.

by the_voder

HTML

<!-- 
Responsive interactive map with "hotspots".
Requires jQuery for button functionality, but hotspots positioned and animated entirely with CSS.
-->

<!-- Hotspot container element -->
<div id="map">

	<!-- Hotspot background image -->		
	<img src="https://maproom.net/wp-content/uploads/02-London-boroughs.png" alt="Hotspots">
	
	<!-- Use anchor (link) elements for hotspots that navigate to other pages (or another place on the same page) -->
	<a href="lewisham" id="hotspot1" class="spots pulse"></a>
	<a href="ealing" id="hotspot2" class="spots pulse"></a>
	
	<!-- Use button elements for hotspots that trigger an action on the current page -->
	<button id="hotspot3" class="spots pulse" data-value="Tower Hamlets"></button>
	<button id="hotspot4" class="spots pulse" data-value="Bexley"></button>

</div>

CSS

/* Hotspots container div */
#map {
  position: relative;
  margin: 0;
  width: 80%;
  /* height set by img inside */
  padding: 0;
}

/* Hotspots background image */
#map img {
  width: 100%;
}

/*
Hotspot elements style
*/
.spots {
  position: absolute;
  display: block;
  /* Move registration point to centre of element. This prevents the hotspots drifting out of place when the image is resized */
  transform: translate(-50%, -50%);
  /* Dimensions in px. Might be good to resize with a media query for smaller displays */
  width: 20px;
  height: 20px;
  /* Suppress border on links */
  border: 0;
  /* Make element circular */
  border-radius: 50%;
  opacity: 0.75;
  /* change cursor to pointer on rollover button elements with this class */
  cursor: pointer;
}

/* Individual hotspot properties */

/* Lewisham link */
#hotspot1 {
  left: 59.5%;
  top: 60.1%;
  background-color: red;
}

/* Ealing link */
#hotspot2 {
  left: 24.6%;
  top: 43.8%;
  background-color: orange;
}

/* Tower Hamlets button */
#hotspot3 {
  left: 56.7%;
  top: 42.25%;
  background-color: purple;
}

/* Bexley button */
#hotspot4 {
  left: 77.2%;
  top: 55.5%;
  background-color: yellow;
}

/*
pulse animation using box-shadow:
https://reactgo.com/css-pulse-animation/
*/

.pulse {
  box-shadow: 0 0 0 0 #000;
  animation: pulse-animation 2s infinite;
}

@keyframes pulse-animation {
	/* Animate box-shadow "spread" value */
  0% {
    box-shadow: 0 0 0 0 rgba(255, 255, 255, 1.0);
  }

  100% {
    box-shadow: 0 0 0 10px rgba(255, 255, 255, 0);
  }
}

JavaScript

/*
Example action triggered on button click
Requires jQuery!
*/

$("button.spots").on("click", function() {

	// Display data attribute "value" of clicked button as alert
	alert($(this).data("value"));
	
});