Тег map (от английского map, «карта») описывает карту-изображение: набор кликабельных областей на одной картинке. Сам тег ничего не рисует. Он хранит области, записанные внутри него тегами area, и получает название, по которому на него ссылается картинка. К географической карте местности тег отношения не имеет, об этом отдельный раздел ниже.
Дальше разобраны принцип работы, атрибуты, то, что записывают внутри, использование с img и object, адаптивные картинки, работа из JavaScript, карта местности, сравнение со ссылкой и svg и причины, по которым области не срабатывают. Другие теги группы собраны в шпаргалке по тегам.
<img src="rooms.png" usemap="#rooms" alt="План квартиры">
<map name="rooms">
<area shape="rect" coords="0,0,100,100" href="kitchen.html"
alt="Кухня">
</map>
В этой статье
- Тег map в HTML: что это и для чего нужен
- Как работает тег map: связь с картинкой через name и usemap
- Атрибуты тега map: name и общие атрибуты
- Какой тег используется внутри тега map
- Тег map для картинки: img, object и одна карта для нескольких картинок
- Тег map и адаптивная картинка: пересчёт координат
- Тег map в JavaScript: areas, name и useMap
- Тег map и карта местности: Open Street Map и iframe
- Тег map, a или svg: чем отличаются
- Почему тег map не работает
Тег map в HTML: что это и для чего нужен
Сначала о том, для чего нужен map и что он делает с картинкой.
Обычная картинка с img ведёт максимум на одну страницу, если её обернуть ссылкой. Тег map позволяет разделить одну картинку на несколько областей и дать каждой свою ссылку: на плане квартиры каждая комната ведёт на свою страницу, на схеме сайта каждый блок — на свой раздел, на фотографии прибора каждая деталь — на своё описание.
Сам map на странице не виден и места не занимает: карта с одной областью внутри имеет размер 0 на 0. Закрывающий тег обязателен. Области в нём записывают тегами area, а картинку подключают атрибутом usemap.
Как работает тег map: связь с картинкой через name и usemap
Связь между картинкой и картой строится по названию: name у карты и usemap у картинки.
У карты записывают name="rooms", у картинки usemap="#rooms". Решётка в usemap обязательна: запись без неё не находит карту, и клики по областям не срабатывают. Регистр важен: карта с name="m" не находится по usemap="#M".
Порядок в разметке не важен: карту можно записать до картинки или после неё, и даже внутри скрытого контейнера с display: none она продолжает работать. Если карт с одним названием две, используется первая в документе, а вторая не учитывается. Если картинка обёрнута ссылкой, клик внутри области уходит в область, а клик вне областей — в ссылку вокруг картинки.
Пример: связь тега map с картинкой через name и usemap
Кнопки меняют записи в разметке. Кликните по картинке: левая половина A закрыта областью, правая B нет. Строка «Последний клик» показывает, куда попал клик: в область или в саму картинку.
Из примера видно ещё два факта. Карта с одним id без name может найтись, но стандарт этого не гарантирует, поэтому name записывают всегда. А атрибут usemap у object не работает: клик по областям туда не доходит.
Атрибуты тега map: name и общие атрибуты
У map один собственный атрибут — name, остальные общие для всех тегов.
| Атрибут | Что делает | Пример |
|---|---|---|
name | Название карты. На него ссылается usemap у картинки | <map name="rooms"> |
id | Общий атрибут. Если записаны оба, стандарт требует одинаковых значений. Карта с одним id без name может найтись, но стандарт этого не гарантирует | <map id="rooms"> |
class и style | Общие атрибуты. У map по умолчанию display: inline | <map name="rooms" class="plan"> |
Правила для значения name: оно не пустое, не содержит пробелов и не повторяется у других карт. Карта с пробелом в названии работает, но стандарт такое название запрещает, поэтому пробелы не записывают. Если название после загрузки страницы поменять из скрипта, связь с картинкой разрывается и клики перестают работать.
Атрибута usemap у самой карты нет: его записывают на картинке. Атрибуты областей (shape, coords, href, alt) записывают в теге area.
Какой тег используется внутри тега map
Внутри map записывают теги area, но допустимы и ссылки с текстом, потому что содержимое карты прозрачное.
Ответ на вопрос «какой тег используется внутри тега map» простой: area. Каждый area описывает одну кликабельную область: форму, координаты, адрес и текстовое описание. Без area карта бесполезна. У области без href клик не срабатывает.
Содержимое map прозрачное: кроме area внутри допустимы текст и ссылки. Они выводятся на странице как обычное строчное содержимое. Карта со ссылкой внутри имеет размер по тексту, и ссылка кликается. Так дублируют области обычными ссылками: те же адреса доступны без клика по картинке.
| Что записано внутри | Что видно на странице | Клик |
|---|---|---|
Только area | Ничего, размер карты 0 на 0 | Работает область |
area и ссылка a | Текст ссылки | Работают область и ссылка |
area, текст и ссылка | Текст и ссылка. С display: block карта занимает всю строку | Работают область и ссылка |
Пример: что записывают внутри тега map
Кнопки меняют содержимое карты. Строки показывают размер карты на странице и её свойство display. Кликните по левой половине картинки и по ссылке: строка «Последний клик» показывает, что сработало.
С клавиатуры по областям с href можно ходить клавишей Tab в порядке записи, а Enter открывает адрес области.
Тег map для картинки: img, object и одна карта для нескольких картинок
Карту можно подключить к img, и одна карта обслуживает сколько угодно картинок.
Рабочий вариант — это img с атрибутом usemap. Одну карту можно подключить к нескольким картинкам: обе картинки с usemap="#m" реагируют на клик в области. Это удобно, когда одна и та же схема выводится в разных местах страницы.
<img src="plan.png" usemap="#plan" alt="План, этаж 1">
<img src="plan-small.png" usemap="#plan" alt="План, этаж 1">
<map name="plan">...</map>
Для object стандарт атрибут usemap не предусматривает, и клик по областям не срабатывает. Поэтому карты-изображения подключают только к img.
Тег map и адаптивная картинка: пересчёт координат
Координаты областей записаны в пикселях и не масштабируются вместе с картинкой, поэтому в адаптивной вёрстке их пересчитывают.
Область 0,0,100,100 занимает первые 100 пикселей картинки при любом размере картинки. Если картинку растянули до 300 пикселей по ширине, область остаётся прежней и закрывает уже не половину, а треть. Это видно в примере: пунктир показывает, где область кликабельна на самом деле.
Пример: тег map и адаптивная картинка
Пунктирный прямоугольник показывает кликабельную область. Когда картинка растянута до 300 на 150, область без пересчёта остаётся маленькой. Третья кнопка пересчитывает координаты по отношению размеров, и область снова закрывает половину A.
Решение: скриптом умножать координаты на отношение текущей ширины картинки к её исходной ширине и делать это при изменении размера окна.
function scaleArea(img, area, base) {
const k = img.clientWidth / img.naturalWidth;
area.coords = base.map((v) => Math.round(v * k)).join(",");
}
Если картинка должна масштабироваться вместе с областями без скрипта, вместо карты берут svg: его фигуры меняют размер вместе с рисунком.
Тег map в JavaScript: areas, name и useMap
Из JavaScript у map есть коллекция areas и свойство name, а у картинки свойство useMap.
Свойство areas возвращает живую коллекцию областей: если добавить в карту ещё один area, число в ней растёт. Свойства images у map в браузере нет. Свойство name совпадает с атрибутом, а useMap у картинки хранит строку вместе с решёткой.
const map = document.querySelector("map");
console.log(map.areas.length);
console.log(map.name);
console.log(img.useMap);
Записать новое значение в img.useMap можно в любой момент: картинка сразу переключается на другую карту. Запись "#none" отключает области, а возврат прежнего значения включает их снова.
Пример: тег map в JavaScript, areas, name и useMap
Кнопки читают свойства карты и картинки. Вторая кнопка добавляет область, и число областей растёт на единицу. Последняя кнопка проверяет, есть ли у карты свойство images.
Тег map и карта местности: Open Street Map и iframe
Тег map не строит карту местности: для неё берут iframe с картой, например с Open Street Map.
Название тега часто понимают буквально, и тогда ищут «теги Open Street Map» или «карта тег map». Но map про картинки: он ничего не знает о координатах на местности, масштабе и улицах. Географическую карту на сайт выводят другим способом.
Самый простой вариант для сайта — это iframe с картой OpenStreetMap. На сайте сервиса в меню «Поделиться» есть пункт с HTML-кодом: он создаёт готовый iframe, и в нём уже указан источник данных. Если карта не нужна внутри страницы, хватит обычной ссылки с координатами.
<iframe width="425" height="300" title="Карта"
src="https://www.openstreetmap.org/export/embed.html?bbox=...">
</iframe>
<a href="https://www.openstreetmap.org/#map=12/46.48/30.72">
Карта
</a>
Данные OpenStreetMap открыты по лицензии ODbL. Главное условие для сайта: указать сервис и его участников как источник и дать ссылку на страницу об авторских правах. Код из окна «Поделиться» обычно уже содержит обратную ссылку.
Тег map, a или svg: чем отличаются
Для нескольких ссылок на одной картинке подходят map и svg, а для одной ссылки хватает обычной ссылки вокруг img.
| Свойство | map и area | Ссылка вокруг img | svg |
|---|---|---|---|
| Число ссылок на одной картинке | Любое | Одна на всю картинку | Любое |
| Форма области | Прямоугольник, круг, многоугольник | Вся картинка | Любая фигура |
| Масштаб | Координаты не масштабируются | Масштабируется с картинкой | Масштабируется вместе с рисунком |
| Текстовый запасной вариант | Ссылки внутри map | Текст в alt | Текст внутри разметки |
| Нужен скрипт при адаптивности | Да, для пересчёта координат | Нет | Нет |
Если ссылка нужна на всю картинку, оборачивают img в тег a. Если областей несколько и картинка растровая, берут map с пересчётом координат. Если картинку можно нарисовать как svg, лучше взять его.
Почему тег map не работает
Если область не срабатывает, причину ищут в связи по названию, в самой области и в размере картинки.
| Причина | Что видно | Что делать |
|---|---|---|
В usemap нет решётки | Клики по областям не работают | Записать usemap="#имя" |
Регистр в usemap и name разный | Карта не найдена | Записать одинаково |
| Нет карты с таким названием | Картинка остаётся обычной | Добавить map с нужным name |
| Две карты с одним названием | Работает только первая в документе | Дать картам разные названия |
usemap записан у object | Области не срабатывают | Взять img |
У area нет href | Клик по области ничего не делает | Записать адрес |
| Картинка растянута, координаты прежние | Область закрывает не то место | Пересчитать координаты скриптом |
| Название карты поменяли из скрипта | Связь разорвана | Менять useMap у картинки вместе с названием |
| Картинка обёрнута ссылкой | Клик вне областей уходит в ссылку | Убрать ссылку вокруг картинки |
Частые ошибки с тегом map
Основные ошибки связаны с записью названия, подключением к object и ожиданием, что карта сама подстроится под размер картинки.
| Ошибка | Что происходит | Как исправить |
|---|---|---|
<img usemap="rooms"> | Без решётки карта не находится | Записать usemap="#rooms" |
<map name="Rooms"> | При usemap="#rooms" карта не найдена, регистр важен | Записать название одинаково |
<map name="my map"> | Стандарт запрещает пробелы в названии | Записать name="my-map" |
<object usemap="#m"> | Области не срабатывают | Подключить карту к img |
<area shape="rect" coords="0,0,9,9"> | Нет href: область не кликается | Записать href и alt |
<map name="m"> и <map name="m"> | Работает только первая карта | Дать разные названия |
Растянули картинку и не поменяли coords | Область смещена относительно рисунка | Пересчитать координаты скриптом |
map.name = "x" после загрузки | Связь с картинкой разорвана | Менять img.useMap одновременно |
Тег map для карты местности | Он ничего не знает о местности | Взять iframe с картой сервиса |