Search code examples
javascripthtmlcssimagearea

Clickable area map on a large image (requiring scrolling) on Wordpress


I have an image that is long (about 2-3 screens long), and I need to make certain points on it clickable to display a descriptive div with an image (like a tooltip). And this is for a Wordpress page. The solutions I've seen online work if the image is smaller than the window, but I need one that works on a long, scrollable image. Any solutions?


Solution

  • Measure everything in terms of the image. Its width, height, central position of each clickable area from left and top of the image and the width and height of each clickable area. These are set as CSS variables and CSS can calculate the relevant %s so the system is responsive, adjusting to any viewport dimensions/aspect ratio.

    The image can then be put as a background to a containing div with the right aspect ratio and a given width. Each child div is a clickable area.

    In this snippet the text about an area simply shows on hover on a pseudo element just for demo purposes. You will probably want to put clickable elements there, perhaps of type radio and reveal more complex info on click.

    The snippet has two clickable areas, scroll down to see the second. They have been given borders just for the demo.

    .bg {
      --w: 500;
      /* measured width of the image */
      --h: 1500;
      /* measured height of the image */
      width: 100vw;
      height: calc(var(--h) / var(--w) * 100vw);
      background-image: url(https://picsum.photos/id/238/500/1500);
      background-size: 100% auto;
      margin: 0;
      padding: 0;
      border: none;
      position: relative;
    }
    
    .bg div {
      position: absolute;
      left: calc((var(--dpx) - (var(--dpw) / 2)) / var(--w) * 100%);
      top: calc((var(--dpy) - (var(--dph) / 2)) / var(--h) * 100%);
      width: calc(var(--dpw) / var(--w) * 100%);
      height: calc(var(--dph) / var(--h) * 100%);
      border: 2px magenta solid;
      /* put in just for demo so you can see the areas */
      display: inline-block;
    }
    
    .bg div[data-point="The very top"] {
      --dpx: 240;
      /* measured distance of the central point of the area from the left of the image */
      --dpy: 65;
      /* measured distance of the central point of the area from the top of the image */
      --dpw: 10;
      /* width of the clickable area */
      --dph: 20;
      /* height of the clickable area */
    }
    
    .bg div[data-point="Water towers"] {
      --dpx: 418;
      --dpy: 1155;
      --dpw: 40;
      --dph: 40;
    }
    
    .bg div:hover::after {
      content: attr(data-point);
      position: absolute;
      top: 0;
      left: 0;
      display: inline-block;
      z-index: 1;
      background-color: black;
      color: white;
    }
    <div class="bg">
      <div data-point="The very top"></div>
      <div data-point="Water towers"></div>
    </div>