Accessible Maps & Geospatial Content
An interactive map is a picture of spatial data. Just like a chart, the accessible version is usually the same information delivered as text and structured controls, not the pixels. So the real work is deciding what job the map is doing, then providing that job as an equivalent path anyone can use, with the visual map layered on top as an enhancement. This guide covers store locators, embedded maps, markers, static maps, and data maps end to end, mapped to WCAG 2.2, with copy-ready HTML.
Why Maps Are Their Own Accessibility Problem
A map is a visual model of spatial relationships. For a sighted mouse user it is intuitive: glance, drag, click a pin, read the popup. For everyone else it can fall apart. A keyboard user meets a widget that may not take focus, or a scatter of pins that are not real controls. A screen reader user meets an unlabeled <div>, or the opposite problem, a firehose of hundreds of markers with no structure. A low-vision user finds the street names are baked into the map tiles as images of text that will not resize or reflow. A user who cannot perform a sustained drag finds that panning works only by dragging.
Trying to make the map canvas itself perfect for all of these people is a losing battle, and usually the wrong goal. The map is almost never the point. The point is the task the map supports: find the nearest store, see where a service is available, understand which regions lead on some metric. That task can be delivered in a form every user can operate, and the accessible version of a map is built around that idea.
The reframe that decides everything
Decide what job the map is doing, then provide that job as text and structured controls, and treat the visual map as an enhancement on top. You do not have to make the pixels accessible; you have to make the task achievable without them. That single principle drives almost every technique in this guide: hide a decorative map, replace a single-location map with an address and a static image, and back an interactive locator or data map with a real list or table that is the source of truth.
This is not a niche concern. Store locators, branch finders, service-area maps, and government service maps are common targets in web accessibility complaints, precisely because a map is often the only way a site lets someone find something they need. Where an organization is covered by the ADA, Section 508, or the European Accessibility Act, a map that carries essential information or function carries the same obligations as the rest of the page. The good news is that the fix, an equivalent path in text, also helps people on slow connections, people who want to copy an address, and search engines indexing your locations.
How Map Accessibility Maps to WCAG 2.2
The highlighted row, 1.1.1 Non-text Content, is the one maps fail most often, because the location or data the map shows lives only in the pixels and never in text. The rest are the criteria a well-built map experience must also satisfy, from keyboard operation to a single-pointer alternative for dragging.
| Criterion | Level | How it applies to maps |
|---|---|---|
| 1.1.1 Non-text Content | A | The map’s information must exist as text: an embedded map needs a title, markers need names, and any location or value shown only on the map must also be available as HTML text. |
| 2.1.1 Keyboard | A | Panning, zooming, and every marker or control must be operable by keyboard, or an equivalent keyboard-operable list must provide the same function. |
| 1.3.1 Info and Relationships | A | A locator’s results are a real list or table, its filters are labeled form controls, and the tie between a result and its marker is programmatic, not visual only. |
| 4.1.2 Name, Role, Value | A | Markers, zoom buttons, and custom controls must expose a real name and role; a marker built from a div with a click handler has neither. |
| 1.4.1 Use of Color | A | Routes, regions, and marker categories must be distinguishable without color alone; add labels, patterns, or a text and table equivalent. |
| 2.4.7 Focus Visible | A | The focused marker or control needs a visible focus indicator that stands out against the busy, variable map background. |
| 1.4.3 Contrast (Minimum) | AA | Your own labels, legends, and overlay text on or beside the map need 4.5:1 (3:1 for large text). |
| 1.4.11 Non-text Contrast | AA | Map controls, route lines, and marker icons need 3:1 against their background; a pale route on a pale map fails. |
| 1.4.10 Reflow | AA | The locator and its controls must reflow to a single column at 320px; baked-in tile text cannot reflow, another reason the data must live in your HTML. |
| 2.5.7 Dragging Movements | AA | Pan-by-drag needs a single-pointer alternative: visible pan and zoom buttons that move the map with a tap or click. |
Each criterion links to its full reference and interactive demo. The complete WCAG 2.2 criteria are one click away.
1. Decide What Job the Map Is Doing
Every accessibility decision about a map flows from one question: what is this map for? Most maps fall into three jobs, and each has a different, much simpler answer than “make the canvas perfect.”
Decorative or illustrative
A stylized map in a hero, a “we are global” backdrop, a texture. It carries no information the user needs. Hide it from assistive technology with aria-hidden="true", or alt="" if it is an <img>, and do not make people tab through it.
One fixed location
A contact page “find us here.” The essential information is the address and how to get there, which belong in text. A static map image with meaningful alt, plus a Get directions link, serves more people than an embedded interactive map.
Explore many places or data
A store locator, a property search, a choropleth. The accessible experience is a list or table of the results or data with the same filters and actions, and the map is a visual layer on top. The list is the source of truth.
Naming the job first is what keeps the work proportionate. Two of the three answers barely touch the map at all. Only the third, the interactive locator or data map, needs the fuller treatment, and even there the heavy lifting happens in the list beside the map, not in the map canvas. The rest of this guide follows that order.
2. The Text Alternative: the Map-plus-List Pattern
This is the centerpiece technique, and it is the geospatial version of a rule you may know from accessible charts: the accessible form of a picture of data is the data itself, as text. For a locator, everything a sighted user reads off the map, which stores exist, where they are, how far, and what you can do about each one, must be available as a real list or table of results with the same actions.
<!-- The accessible source of truth: a labeled search, a live count, and a real list -->
<form role="search" aria-label="Find a store">
<label for="near">Search near</label>
<input id="near" name="near" type="text" autocomplete="postal-code">
<button type="submit">Search</button>
</form>
<!-- Announce how many results the search returned -->
<p aria-live="polite">12 stores found near 90210.</p>
<ul aria-label="Store search results">
<li>
<h3>Acme Coffee, Central</h3>
<p>5th and Main, Springfield · 0.4 miles · Open until 8pm</p>
<a href="https://maps.example/dir?to=acme-central">Get directions</a>
<button type="button" data-store="acme-central">Show on map</button>
</li>
<li>
<h3>Acme Coffee, Riverside</h3>
<p>18 Canal Street, Springfield · 1.1 miles · Open until 6pm</p>
<a href="https://maps.example/dir?to=acme-riverside">Get directions</a>
<button type="button" data-store="acme-riverside">Show on map</button>
</li>
</ul>A few rules make this pattern hold together:
- The list is the source of truth; the map mirrors it. Build the list first and wire the map to it, so the
Show on mapbutton pans the map to a result. A keyboard or screen reader user completes the whole task, search, read results, get directions, from the list, never needing to touch the map. - Announce result changes. When a search or filter updates the results, update a polite live region with the new count, so a screen reader user knows the page responded rather than being left in silence.
- Use real structure. Results are a genuine
<ul>or a semantic data table, the filters are labeled form controls, and each result’s actions are real links and buttons with names that identify the place.
Do not dump every marker into the DOM as a focusable element
Making a locator accessible does not mean turning five hundred pins into five hundred tab stops. That is its own failure: a keyboard user tabs forever and a screen reader user hears an endless list of markers. Filter to a manageable set, paginate or cluster the rest, and let the results list, not the raw markers, be how people move through locations. Reach a place by reading its list entry, not by tabbing across the map.
3. Static Maps: the Simplest Accessible Answer
For the “one fixed location” job, a static map image is simpler and more robust than an interactive embed. A static image from a maps provider, or even a screenshot, with real alt text and the address written out beside it, gives everyone the information without a widget to operate, a script to load, or a keyboard trap to escape.
<!-- A static map: the location lives in the alt text AND in real HTML beside it -->
<figure>
<img
src="/static-map-acme-central.png"
alt="Map showing Acme Coffee at 5th and Main, two blocks north of Central Station"
width="600" height="300" style="max-width:100%;height:auto;">
<figcaption>
<address>
Acme Coffee, 5th and Main, Springfield
</address>
<a href="https://maps.example/dir?to=acme-central">Get directions</a>
</figcaption>
</figure>
<!-- Decorative map, with the address already in text nearby: skip it -->
<img src="/hero-map-texture.png" alt="" aria-hidden="true">- Alt text carries the meaning, not the word “map.” Describe what the map tells the reader in context, the place and where it sits, since a pin on a tile conveys nothing to a screen reader. This is a straight application of 1.1.1 Non-text Content.
- Always pair it with the address as live text. Put the address in real HTML, ideally in an
<address>element, plus a Get directions link that hands off to the user’s maps app. Do not let the only copy of the address be baked into the image, which also fails 1.4.5 Images of Text and 1.4.10 Reflow. - A decorative map gets an empty alt. If the map is purely illustrative and the real address is already text nearby, use
alt=""so assistive technology skips the redundant image rather than describing it.
4. Interactive and Embedded Maps
When you do need a live map, the two common forms are an embedded iframe from a provider and a JavaScript map built with a library such as Leaflet, Mapbox GL, Google Maps, or OpenLayers. Both need work, and neither removes your obligation to provide the list for the real interaction.
Embedded iframe maps
An embedded map is an <iframe>, and every iframe needs a titleso a screen reader announces what the frame contains instead of just “frame.” The title satisfies 4.1.2 Name, Role, Value for the frame, but it does not make the map’s contents operable, so the list still carries the task.
<!-- An embedded map needs a descriptive title; the list still does the real work -->
<iframe
title="Map of Acme Coffee store locations in Springfield"
src="https://maps.example/embed?q=acme+springfield"
width="600" height="450" style="border:0;max-width:100%;"
loading="lazy"></iframe>JavaScript map libraries
A scripted map needs an accessible name and a keyboard story:
- Name the map container. Give the map element an
aria-labelsuch as “Map of store locations” so it is announced as a meaningful region rather than an anonymous block. - Make pan and zoom keyboard operable. Most libraries can pan with the arrow keys and zoom with
+and-once the map has focus (Leaflet enables this by default and makes the map focusable), but do not stop there. Surface visible, focusable zoom and pan buttons so the controls are discoverable and satisfy 2.1.1 Keyboard. - Those buttons are also your 2.5.7 answer. Panning by mouse drag is a dragging movement, so it needs a single-pointer alternative. Pan and zoom buttons that move the map with one tap satisfy 2.5.7 Dragging Movements. Make sure the library’s controls are enabled and reachable rather than hidden.
role="application" is a loaded gun
Putting role="application" on a map tells the screen reader to stop intercepting keys and pass them to the widget, which switches off the browse-mode reading commands blind users depend on. Only use it if you have genuinely built full keyboard operation for everything inside, panning, zooming, reaching and reading every marker. If you have not, it traps the user in a region where their normal commands no longer work and nothing replaces them. The safer default is a labeled region and letting the list carry the interaction.
5. Markers, Pins, and Popups
When markers are interactive, they have to be real controls. A pin a mouse user can click must be a <button> or an <a>, focusable and named, not a <div> or an <img> with a click handler that no keyboard can reach and no screen reader can find. The accessible name must identify the place, not describe the graphic.
<!-- A marker is a real, named button, not a div with an onclick -->
<button type="button" class="marker" data-store="acme-central"
aria-label="Acme Coffee, 5th and Main. Show details.">
<img src="/pin.svg" alt="" width="24" height="32">
</button>- Name every marker by its place. “Acme Coffee, 5th and Main” tells a screen reader user which location they are on. “Marker” or a pin file name tells them nothing (4.1.2). The pin image inside gets an empty alt, since the button already carries the name.
- Treat the popup like a dialog. When a marker opens an infowindow, move focus into it, let Escape close it and return focus to the marker, and build its content from real HTML. This is the dialog and disclosure pattern applied to the map.
- Do not signal a marker’s meaning by color alone. If a red pin means “closed” and a green pin means “open,” that difference must also be in the accessible name or a text label, not the color of the icon (1.4.1 Use of Color).
- Mind the scale. Hundreds of markers become hundreds of tab stops. Cluster them, or keep the list as the primary way people reach a location and let direct marker interaction be an enhancement, not the only route.
6. Color, Contrast, and Text on Maps
Maps are visually dense, which makes contrast and color harder than on a plain page, and the provider’s own tiles are outside your control. That is one more reason the important information also lives in your HTML, but there is still plenty you own on top of the map.
- Baked-in tile text cannot resize or reflow. Street and label text rendered into map tiles is an image of text, so it does not respond to 1.4.4 Resize Text or 1.4.10 Reflow. You cannot fix the provider’s tiles, so keep your own overlay labels, legends, and callouts as live HTML text, and offer zoom controls so users can enlarge the view.
- Give controls, routes, and markers 3:1 non-text contrast. Zoom buttons, your custom controls, route lines, and marker icons all need 3:1 against the background under 1.4.11 Non-text Contrast. A thin pale route drawn over a pale map fails, so give routes and markers a contrasting outline or casing that holds up over a variable background.
- Never encode meaning in color alone. Colored routes, regions, and categories need a second cue, a label, a pattern, or a text and table equivalent, so a color-blind user gets the same information (1.4.1).
- Keep the focus indicator visible. A focused marker or control needs a clear focus ring that stands out against the map (2.4.7 Focus Visible). A subtle default outline vanishes over busy tiles.
7. Data Maps: a Choropleth Is a Chart
A choropleth, a heat map, or a bubble map is not really a map in the navigational sense. It is a data visualization that uses geography for its axes, encoding a value in the color or size of each region. That means the same rule as any chart applies: the accessible form is the underlying data as a table, region by value, plus a short text summary of the takeaway.
<!-- A choropleth needs its data as a table and a plain-language summary -->
<figure>
<div role="img" aria-label="Choropleth of 2026 sales by US region">
<!-- the colored SVG or canvas map -->
</div>
<figcaption>Sales were highest in the West and lowest in the Northeast.</figcaption>
</figure>
<table>
<caption>2026 sales by region (US dollars, millions)</caption>
<thead>
<tr><th scope="col">Region</th><th scope="col">Sales</th></tr>
</thead>
<tbody>
<tr><th scope="row">West</th><td>48.2</td></tr>
<tr><th scope="row">South</th><td>39.7</td></tr>
<tr><th scope="row">Midwest</th><td>31.4</td></tr>
<tr><th scope="row">Northeast</th><td>22.9</td></tr>
</tbody>
</table>Do not make the colored map the only way to read the numbers, and do not rely on color alone to separate categories. The accessible charts guide covers the data-table-as-text-alternative pattern in full, and the accessible data tables guide covers building the table itself with a caption and th scope headers. Both apply directly to a map that is really a chart.
8. Testing an Accessible Map
The most important test is whether the task works without the map, so start there and only then check the map itself. Automated tools catch a missing iframe title and some unlabeled controls, but they cannot tell you whether an equivalent non-map path exists, which is the thing that matters most.
Keyboard only, without touching the map
Put the mouse away and complete the whole task from the list: search or filter, read the results, get directions, select a location. If you can do that without ever entering the map, the core experience is sound. Then Tab into the map itself and confirm you can pan and zoom with the keyboard, reach any markers, and that the map is skippable rather than a trap.
Screen reader
With NVDA, VoiceOver, or TalkBack, confirm each result and its actions are announced, that the result count is announced when it changes, and that the map is either a cleanly labeled, skippable region or exposes named controls, not a wall of unlabeled pins.
Zoom, pointer, and contrast
At 200% browser zoom and 320px width, confirm the locator list and controls reflow to a single column and the page does not scroll sideways. Confirm every drag has a single-pointer alternative and pinch-zoom has button equivalents (2.5.7). Check that your controls, routes, and markers meet 3:1 contrast. For where this fits in a wider process, see the accessibility audit guide and the automated versus manual testing guide, which explains why the manual pass is the one that catches what matters here.
Common Map Accessibility Mistakes & How to Fix Them
These are the errors that turn up most in real map audits. Every one comes back to the same root cause: the map is treated as the experience, instead of an enhancement on top of an experience that already works without it.
| Anti-pattern | Why it fails | The fix |
|---|---|---|
| The map is the only way to find a location or read the data. | A keyboard or screen reader user who cannot operate the map has no path to the information at all, so the task is impossible for them (fails 1.1.1 and 2.1.1). | Provide an equivalent non-map path: a list or table of the locations or data with the same details and actions, usable entirely without the map. |
| An embedded map iframe with no title. | A screen reader announces only "frame" with no idea what it contains, so the user cannot tell whether it matters or what to do with it (fails 4.1.2 and 1.1.1). | Give the iframe a descriptive title that says what the map shows, for example "Map of Acme store locations", and still provide the list. |
| Markers are divs or images with click handlers. | They are not focusable and expose no name or role, so a keyboard user cannot reach them and a screen reader user does not know they exist (fails 2.1.1 and 4.1.2). | Use real button or anchor elements whose accessible name identifies the place, or drive selection from the accessible results list instead. |
| Panning and zooming work only by mouse drag, scroll, or pinch. | There is no keyboard path and no single-pointer alternative, excluding keyboard users and people who cannot perform a sustained drag (fails 2.1.1 and 2.5.7). | Add keyboard support and visible pan and zoom buttons that move the map with a single tap or click. |
| role="application" on a map with no real keyboard implementation. | It suppresses the screen reader's browse-mode reading commands but offers nothing operable in their place, trapping the user in an unusable region. | Expose the map as a labeled region and carry the real interaction in the list, or actually build and test full keyboard operation before using role="application". |
| Address, hours, or values baked into the map image or a marker tooltip only. | That text cannot be read by a screen reader, resized, or reflowed, and it disappears if the map fails to load (fails 1.1.1, 1.4.4, and 1.4.10). | Put the address, hours, and any data in live HTML text beside the map, and use the map to reinforce it rather than to hold it. |
The Accessible Map Checklist
- The job is named. You know whether this map is decorative, shows one location, or lets people explore many, and you have built the matching answer.
- There is an equivalent non-map path. Anything the map is the way to do, find a store, read a value, can also be done from a list, table, or text without the map.
- The list is the source of truth. Results are a real list or table with the same details and actions, and the map is wired to the list, not the reverse.
- Result changes are announced. A search or filter updates a polite live region with the new count so screen reader users know the page responded.
- Embedded maps have a title. Every map
<iframe>has a descriptivetitle, and decorative maps are hidden from assistive technology. - Markers are real, named controls. Interactive pins are buttons or links whose name identifies the place, and popups behave like dialogs with focus and Escape.
- Pan and zoom work by keyboard and by tap. Visible pan and zoom buttons operate the map with a single click, satisfying both keyboard and single-pointer requirements.
- Nothing depends on color alone. Routes, regions, and marker categories carry a label, pattern, or text equivalent as well as color.
- Contrast and focus hold up on the map. Controls, routes, and markers meet 3:1, and the focus indicator stays visible against busy tiles.
- A data map ships its data. A choropleth or heat map includes the underlying values as a table and a plain-language summary of the takeaway.
Build the Equivalent Path First
A map is easy once the task works without it. Start with the two techniques that carry an accessible map: a real results list or table, and a single-pointer alternative to every drag.
Frequently Asked Questions
Do interactive maps have to be accessible?▾
Yes, when the map delivers information or a function people need. A store locator that is the only way to find a branch, a service-area map, a transit map, or a data map that carries a statistic are all covered by the same accessibility obligations as the rest of the page, and store locators in particular are a recurring subject of ADA web accessibility complaints. The important nuance is how you satisfy the requirement: you rarely have to make the map canvas itself perfect. You have to make the task the map supports achievable without the map, by providing an equivalent path in text and structured controls. A purely decorative map that carries no information can simply be hidden from assistive technology instead.
What is the best way to make a store locator accessible?▾
Build it as a map plus a list, and treat the list as the source of truth. The accessible experience is a labeled search or filter form and a real list or table of results, where each result gives the name, address, distance, and hours as text and offers the same actions as the map, such as a Get directions link and a Select control. Wire the visual map to that list so selecting a result updates the map, never the other way around. A screen reader user or a keyboard-only user should be able to search, read the results, and get directions to a location without ever interacting with the map. When the result count changes, announce it with a live region. The map then becomes a helpful visual enhancement layered on top of an experience that already works without it.
Is Google Maps or an embedded map accessible by default?▾
Partly, and not enough to rely on. A Google Maps embed and the major mapping libraries include some keyboard support and some assistive-technology labeling, and that is genuinely better than a hand-built canvas with nothing. But an embed still needs a descriptive title on its iframe so a screen reader announces what the frame contains, and it still does not, on its own, give a non-visual user a usable way to complete your specific task, such as finding the nearest of your twelve stores. You still owe an equivalent non-map path, the list, and you still need to test the keyboard and screen reader experience yourself rather than assuming the provider handled it. Treat the provider's accessibility as a starting point, not a finished job.
How do I write alt text for a map image?▾
Describe what the map communicates in this context, not the fact that it is a map. For a contact page, alt text such as "Map showing Acme Coffee at 5th and Main, two blocks north of Central Station" carries the useful information, whereas "map" carries none. A pin dropped on a tile does not tell a screen reader anything, so the location has to live in the alt text or, better, in real HTML text next to the image. Always pair a static map with the address written out as live text and a Get directions link, which is what most people use anyway. If the map is purely decorative and the address is already in text nearby, give the image an empty alt attribute so it is skipped rather than described redundantly.
Should I put role="application" on my map?▾
Usually no. role="application" tells a screen reader to stop intercepting keystrokes and pass them straight to the widget, which switches off the browse-mode shortcuts blind users rely on to read and navigate. That is only appropriate if you have genuinely implemented full keyboard operation for everything inside the map, panning, zooming, reaching and activating every marker, and reading their information. If you have not, role="application" traps the user in a region where their normal reading commands no longer work and there is nothing to operate in their place. The safer default is to expose the map as a labeled region or group, give it an accessible name, and let the list carry the real interaction. Reach for role="application" only when you have built and tested the keyboard experience to match it.
How do people who cannot see the map get the location?▾
From text and controls that sit alongside the map, not from the map itself. The address is written out as live HTML text, there is a Get directions link that hands off to the user's preferred maps app, and for a locator there is a list of results with distances and actions. This is the same principle as an image needing a text alternative: whatever the map shows a sighted user, a non-visual user gets the equivalent in a form their assistive technology can read. Designing this way helps far more people than screen reader users. It also serves anyone on a slow connection where the map has not loaded, anyone who prefers to copy an address as text, and search engines indexing your locations.
How do I make map markers keyboard accessible?▾
Every marker a mouse user can click must be a real, focusable, named control, a button or a link, not a div or an image with a click handler bolted on. Its accessible name must identify the place, for example "Acme Coffee, 5th and Main", rather than "marker" or the file name of a pin graphic. The popup or infowindow that opens when a marker is activated behaves like a dialog: move focus into it, let Escape close it, and build its content from real HTML. The harder problem is scale. Hundreds of markers become hundreds of tab stops and a wall of announcements, so cluster them, or better, make the list the primary way people reach a location and keep direct marker interaction as an enhancement rather than the only route.
How do I make a data map like a choropleth or heat map accessible?▾
Treat it as a chart that happens to use geography for its axes. A choropleth, heat map, or bubble map encodes data in color or size across regions, and just like any data visualization its accessible form is the underlying data as a table, region by value, plus a short text summary of the takeaway, for example "Sales were highest in the West region and lowest in the Northeast." Do not make the colored map the only way to read the numbers, and do not rely on color alone to distinguish categories, which fails Use of Color. The accessible charts guide covers the data-table-as-text-alternative pattern in depth, and it applies directly to maps that are really data visualizations.
Essential Accessibility Resources
Comprehensive tools, checklists, and guides to help you create inclusive digital experiences