image-map

Modern responsive image map with percentage-based coordinates, rich HTML tooltips, keyboard navigation, and progressive enhancement.

Overview

The <image-map> component replaces native HTML <map>/<area> with percentage-based coordinates that scale responsively. Areas are defined as <map-area> children with rich HTML tooltip content, full keyboard navigation, and progressive enhancement.

<image-map> <img src="/maps/floor-plan.svg" alt="Office floor plan" /> <map-area shape="rect" coords="5 8 40 44" label="Conference Hall" href="/rooms/conference"> <strong>Conference Hall</strong> <p>Seats 120 people. AV equipment available.</p> </map-area> <map-area shape="circle" coords="62.5 32 10" label="Server Room" href="/rooms/server"> <strong>Server Room</strong> <p>24 racks, climate controlled.</p> </map-area> <map-area shape="rect" coords="60 56 95 92" label="Open Office" href="/rooms/office"> <strong>Open Office</strong> <p>80 hot-desk workstations.</p> </map-area> </image-map>

Markup Pattern

Place an <img> as a direct child of <image-map>. The component adopts it and overlays an SVG hit-testing layer. Each <map-area> defines a hotspot region — its inner HTML becomes the tooltip content.

Alternatively, src and alt attributes on <image-map> itself can create the image, but placing <img> as a child gives better progressive enhancement.

Coordinate System

All coordinates are percentages (0–100) of the rendered image dimensions — not pixels. Values are unitless numbers separated by spaces or commas. The SVG overlay uses viewBox="0 0 100 100" so percentage coordinates map directly to SVG units with no runtime conversion.

<!-- Rectangle: x1 y1 x2 y2 --> <map-area shape="rect" coords="5 8 40 44" label="Conference Hall">...</map-area> <!-- Circle: cx cy radius --> <map-area shape="circle" coords="62.5 32 10" label="Server Room">...</map-area> <!-- Polygon: x1 y1 x2 y2 x3 y3 ... --> <map-area shape="poly" coords="60 56 95 56 95 92 70 92 60 76" label="Open Office">...</map-area>
ShapeCoords formatDescription
rect x1 y1 x2 y2 Top-left and bottom-right corners
circle cx cy r Centre point and radius (radius is % of image width)
poly x1 y1 x2 y2 ... Series of points (minimum 3), auto-closes

All Shapes Demo

Tooltip Content

The inner HTML of each <map-area> becomes the tooltip content. Use any HTML: headings, paragraphs, lists, images, links.

Tooltip modes

By default, tooltips show on hover (tooltip="hover"). Set tooltip="click" for click-to-toggle, which is better for tooltips with interactive content like links. Set tooltip="none" to disable tooltips entirely.

<map-area shape="rect" coords="5 8 40 44" label="Conference Hall" tooltip="click"> <strong>Conference Hall</strong> <p>Click to see details. Click again to dismiss.</p> <p><a href="/book">Book this room</a></p> </map-area>

CSS Custom Properties

PropertyDefaultDescription
--map-area-color oklch(60% 0.2 250 / 0.08) Default area fill (subtle hint)
--map-area-color-hover oklch(60% 0.2 250 / 0.35) Hover/focus area fill
--map-area-stroke oklch(60% 0.2 250 / 0.3) Default area outline stroke
--map-tooltip-bg oklch(15% 0 0 / 0.92) Tooltip background
--map-tooltip-color white Tooltip text colour
--map-tooltip-radius 0.5rem Tooltip border radius
--map-tooltip-max-width 20rem Tooltip maximum width
image-map { --map-area-color: oklch(55% 0.2 140 / 0.3); --map-area-color-hover: oklch(55% 0.2 140 / 0.6); --map-tooltip-bg: oklch(20% 0.02 220 / 0.95); --map-tooltip-radius: 0.75rem; --map-tooltip-max-width: 24rem; }

Attributes

<image-map>

AttributeTypeDescription
src string Image URL (fallback if no child <img>)
alt string Image alt text (fallback if no child <img>)
aria-label string Accessible label for the map group (defaults to img alt)

<map-area>

AttributeTypeRequiredDescription
shape string Yes rect, circle, or poly
coords string Yes Space or comma-separated percentage values (0–100)
label string Yes Accessible name for the hotspot
href string No Navigation target. Creates an <a> focus anchor
target string No Link target (_blank, etc.)
tooltip string No hover (default), click, or none
disabled boolean No Suppresses interaction and tooltip

Events

EventDetailDescription
image-map:area-enter { area } Pointer or focus entered an area
image-map:area-leave { area } Pointer or focus left an area
image-map:area-activate { area } Area clicked or Enter pressed
const map = document.querySelector('image-map'); map.addEventListener('image-map:area-enter', (e) => { console.log('Entered:', e.detail.area.label); }); map.addEventListener('image-map:area-activate', (e) => { console.log('Activated:', e.detail.area.label); });

Keyboard Navigation

KeyAction
TabMove focus between area anchors
/ Focus next area
/ Focus previous area
Enter / SpaceActivate area (follow link or dispatch event)
EscapeDismiss tooltip

Accessibility

Each <map-area> generates a focusable anchor element (<a> when href is set, <button> otherwise) with aria-label matching the area’s label attribute. The SVG overlay is aria-hidden — it handles only pointer hit-testing. The tooltip uses role="tooltip" and aria-live="polite" for screen reader announcements.

The host element uses role="group" with an aria-label derived from the image alt text.

Progressive Enhancement

<!-- Without JS, image renders normally --> <!-- map-area elements display as a labeled list --> <image-map> <img src="plan.svg" alt="Floor plan" /> <map-area shape="rect" coords="..." label="Room A" href="/a"> tooltip content (hidden without JS) </map-area> </image-map> <!-- Renders as: [image] • Room A -->

Touch Behaviour

On touch devices with tooltip="hover", a two-tap pattern is used: the first tap shows the tooltip, the second tap navigates (if href is set). For tooltip="click", tapping toggles the tooltip on/off. Press Escape or tap elsewhere to dismiss.

Related

  • tool-tip — General-purpose tooltip component
  • geo-map — Interactive geographic maps
  • compare-surface — Before/after image comparison
  • map — Native HTML image map (pixel-based)
  • area — Native HTML area element