Всплывающие окна (popup) и подсказки (tooltip) в Leaflet представляют собой DOM-элементы, которые добавляются поверх карты и управляются встроенной системой позиционирования. Несмотря на то что они создаются через JavaScript API, их внешний вид полностью контролируется через CSS и дополнительные классы, передаваемые при создании.
Popup формируется как контейнер с несколькими вложенными слоями:
.leaflet-popup.leaflet-popup-content-wrapper.leaflet-popup-content.leaflet-popup-tipTooltip имеет более простую структуру:
.leaflet-tooltip.leaflet-tooltip-top, .leaflet-tooltip-bottom
и т.д.)Эта структура определяет ключевые точки стилизации: фон, рамки, тени, размеры и поведение при позиционировании.
Основной способ изменения внешнего вида popup — переопределение стандартных классов.
.leaflet-popup-content-wrapper {
background: #1e1e1e;
color: #ffffff;
border-radius: 12px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}
.leaflet-popup-content {
font-size: 14px;
line-height: 1.5;
margin: 10px 14px;
}
.leaflet-popup-tip {
background: #1e1e1e;
}
Ключевой момент заключается в том, что wrapper и
tip должны иметь одинаковый фон, иначе стрелка будет
визуально отделяться от окна.
Leaflet позволяет добавлять собственные CSS-классы, не затрагивая глобальные стили.
L.marker([51.5, -0.09])
.addTo(map)
.bindPopup('<b>Объект</b><br>Описание объекта', {
className: 'custom-popup'
});
CSS:
.custom-popup .leaflet-popup-content-wrapper {
background: linear-gradient(135deg, #2b2b2b, #1a1a1a);
border: 1px solid #444;
}
.custom-popup .leaflet-popup-content {
color: #f0f0f0;
}
Такой подход позволяет создавать множество тем оформления без конфликтов с базовой стилизацией.
При глубокой кастомизации часто требуется изменить не только цвета, но и геометрию элементов.
.leaflet-popup-content-wrapper {
border-radius: 0;
padding: 0;
}
.leaflet-popup-content {
margin: 0;
padding: 16px;
}
.leaflet-popup-tip {
width: 14px;
height: 14px;
transform: rotate(45deg);
margin-top: -7px;
}
В этом случае popup начинает напоминать UI-компонент из интерфейса приложения, а не стандартный блок карты.
Размер popup зависит от содержимого, но можно задать ограничения:
.leaflet-popup-content-wrapper {
max-width: 280px;
min-width: 180px;
}
.leaflet-popup-content {
max-height: 200px;
overflow-y: auto;
}
Такое поведение особенно важно при выводе динамических данных (списки, таблицы, JSON-структуры).
Tooltip чаще используется для кратких подписей и требует более лёгкого визуального оформления.
.leaflet-tooltip {
background-color: rgba(20, 20, 20, 0.9);
color: #fff;
border: none;
border-radius: 6px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
font-size: 12px;
padding: 4px 8px;
}
Tooltip по умолчанию имеет «стрелку», которая также стилизуется через псевдоэлементы:
.leaflet-tooltip:before {
border-top-color: rgba(20, 20, 20, 0.9);
}
При создании tooltip можно задавать направление и поведение:
marker.bindTooltip('Подпись', {
permanent: true,
direction: 'top',
offset: [0, -10]
});
Влияние параметров:
direction — определяет сторону отображения
(top, bottom, left,
right, center)offset — смещение относительно точки привязкиpermanent — фиксированное отображение без hoversticky — следование за курсоромЭти параметры напрямую влияют на применяемые CSS-классы
(leaflet-tooltip-top, leaflet-tooltip-bottom и
т.д.), что позволяет строить адаптивную стилизацию.
Popup и tooltip используют разные подходы к визуальной плотности:
Это отражается в CSS:
Popup поддерживает произвольный HTML, что позволяет внедрять сложные интерфейсные элементы.
L.marker([51.5, -0.09]).addTo(map).bindPopup(`
<div class="card">
<h3>Объект</h3>
<p>Описание</p>
<button class="action">Подробнее</button>
</div>
`);
CSS:
.card h3 {
margin: 0 0 8px;
font-size: 16px;
}
.card .action {
background: #3b82f6;
border: none;
padding: 6px 10px;
color: white;
border-radius: 4px;
cursor: pointer;
}
Важно учитывать, что popup не изолирует стили, поэтому глобальные CSS-правила могут влиять на его содержимое.
Popup использует CSS-анимацию через класс
.leaflet-fade-anim:
.leaflet-fade-anim .leaflet-popup {
transition: opacity 0.2s ease, transform 0.2s ease;
}
Можно переопределять поведение:
.leaflet-popup {
transition: none;
}
Отключение анимации часто применяется в высоконагруженных приложениях или при синхронном обновлении данных.
При масштабных проектах стили popup и tooltip обычно выносятся в систему тем:
:root {
--popup-bg: #1f2937;
--popup-text: #f9fafb;
--tooltip-bg: rgba(17, 24, 39, 0.9);
}
.leaflet-popup-content-wrapper {
background: var(--popup-bg);
color: var(--popup-text);
}
.leaflet-tooltip {
background: var(--tooltip-bg);
}
Такой подход позволяет переключать темы без переработки структуры компонентов.
Стрелка popup (.leaflet-popup-tip) часто требует
отдельной корректировки при нестандартных дизайнах:
.leaflet-popup-tip {
border: 1px solid #444;
box-shadow: none;
}
При изменении углов скругления важно синхронизировать форму tip с контейнером, иначе возникает визуальный разрыв между элементами.
Иногда стили зависят от данных объекта:
const severityClass = severity === 'high'
? 'popup-high'
: 'popup-normal';
L.marker([51.5, -0.09])
.addTo(map)
.bindPopup(`<div class="${severityClass}">Событие</div>`);
CSS:
.popup-high {
border-left: 4px solid #ef4444;
}
.popup-normal {
border-left: 4px solid #22c55e;
}
Такой подход позволяет связывать визуальный стиль с состоянием данных.
Popup и tooltip автоматически пересчитывают позицию при изменении масштаба карты. Однако стили могут влиять на производительность:
Оптимизированные стили обычно минимизируют визуальные эффекты и используют простые цвета и тени.