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"));
});