Map with hover effect and page or (preferably) modal open

Hi @dan or any other helpers :slight_smile:
I have a client that wants me to develop a site with a map function on one of his pages, similar to this one: Martyrs for Christ

The site will be build entirely with Elements. I just have no idea where to even start with something like this.I think the top example is made in HTML code.

If you hover over a certain country then the name should appear and if you click on it then preferably a modal should open with relevant information. In the linked example it opens on a new page which is just too big because there are about 50 countries that need descriptions.

Is there any one that can HELP please :slight_smile:
It will be highly appreciated.

1 Like

That looks like it would require some very specialised code to achieve.

You could build this in Elements, but it would 100% have to be a custom component, and it would certainly require a fairly experienced coder to build it, afaik.

@elementsbot Do you have any further thoughts on building an interactive map like the one on Martyrs for Christ?

Absolutely! Here’s a roadmap for building an interactive map like the Martyrs for Christ example—all inside Elements, while keeping things as approachable as possible.

The Essentials

To build a fully interactive map (with hover effects on each country and modals that pop up with country info), you’ll need a custom component using SVG, Tailwind CSS, and Alpine.js—all technologies natively supported by Elements.

How It Works

  • SVG Map: Embed an SVG file of the world (or your required region) directly within an HTML Component or custom element. Each country will be its own <path> or <g> with a unique id or data-attribute.
  • Hover Effect: Use Tailwind classes for hover styling (hover:fill-blue-500, etc.) or apply Alpine.js to handle hover labels showing country names.
  • Click for Modal: Each country responds to clicks, triggering an Alpine.js modal with the relevant content for that country.

Example Walkthrough

Let’s say you want to highlight three countries for a prototype. Here’s a simplified (but working!) example of how you could wire this up in Elements:

<div 
  x-data="{ country: null }" 
  class="relative w-full max-w-3xl mx-auto"
>
  <!-- SVG MAP -->
  <svg viewBox="0 0 800 400" class="w-full h-auto">
    <!-- Example: Country 1 -->
    <g 
      @mouseenter="country = 'Country A'" 
      @mouseleave="country = null"
      @click="country = 'Country A'; $refs.modal.showModal()"
      class="cursor-pointer"
    >
      <title>Country A</title>
      <path d="M100,150 L200,150 L200,250 L100,250 Z" class="fill-gray-300 hover:fill-blue-400 transition"/>
    </g>
    <!-- Repeat for other countries -->
    <g 
      @mouseenter="country = 'Country B'" 
      @mouseleave="country = null"
      @click="country = 'Country B'; $refs.modal.showModal()"
      class="cursor-pointer"
    >
      <title>Country B</title>
      <path d="M250,100 L350,100 L350,200 L250,200 Z" class="fill-gray-300 hover:fill-green-400 transition"/>
    </g>
  </svg>

  <!-- Country Name Tooltip -->
  <div 
    x-show="country" 
    class="absolute top-0 left-1/2 transform -translate-x-1/2 bg-black text-white px-2 py-1 rounded shadow z-10"
    x-text="country"
  ></div>

  <!-- Country Modal -->
  <dialog x-ref="modal" @close="country = null" class="rounded-lg shadow-lg p-6 w-full max-w-md mx-auto z-50">
    <h2 class="text-2xl font-bold mb-4" x-text="country"></h2>
    <div>
      <template x-if="country === 'Country A'">
        <div>Info about Country A...</div>
      </template>
      <template x-if="country === 'Country B'">
        <div>Info about Country B...</div>
      </template>
      <!-- Add more as needed -->
    </div>
    <button 
      @click="$refs.modal.close()" 
      class="mt-6 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-700 transition"
    >
      Close
    </button>
  </dialog>
</div>

What to Adapt

  • SVG Paths: You can create or export an SVG map from a vector app (like Illustrator or Figma), then split each country into its own <g> or <path>.
  • Country Data: Expand the modal content for all your countries.
  • Styling: Use Tailwind for all visual tweaks.
  • Accessibility: Add appropriate aria- labels and focus management for real-world sites (Elements and Alpine help with this).

Tips to Power Up Your Map (The Elements Way!)

  • Reuse: Once done, package this as a custom component for reuse across multiple projects.
  • Responsive: Tailwind’s utilities make it easy to keep the map crisp on all devices.
  • Resources: SVG maps for free (find one that suits you, and customize it).

Summary:
Building this in Elements is 100% doable, but it’s a moderately advanced task (SVG wrangling and Alpine.js knowledge help). Once set up, you’ll have a super-slick, future-proof, no-vendor-lock-in map ready for any client.

If you want to dig deeper, check out the Elements Custom Components documentation, or just reply here and we can walk through step-by-step with your map SVG!

Let me know if you want a more detailed starter file, or if you’d like any part broken down further—@elementsbot is always happy to help!

I pasted the code into a Custom Component in Elements, and while it’s very basic, it totally works. So, I think the bot is on the right track with his suggested solution…

Thanks @dan. I will look into this and get back as I think I may need some more support. First will look for the right map and then take it from there.