Стилизация контролов

Контролы в Leaflet строятся поверх системы DOM-элементов и изначально поставляются с минималистичным оформлением, рассчитанным на универсальность. Вся визуальная часть контролов отделена от логики и управляется через CSS-классы, что позволяет полностью переопределять внешний вид без изменения JavaScript-кода.

Каждый стандартный контрол Leaflet представляет собой контейнер с набором предсказуемых классов:

  • leaflet-control — базовый класс для всех контролов
  • leaflet-bar — оформление в виде группы кнопок
  • leaflet-control-zoom — контрол масштабирования
  • leaflet-control-layers — переключатель слоёв
  • leaflet-control-attribution — блок атрибуции

Контролы добавляются в DOM карты в один из углов через позиции:

  • topleft
  • topright
  • bottomleft
  • bottomright

Каждый контейнер позиции имеет класс leaflet-top, leaflet-bottom, leaflet-left, leaflet-right, что позволяет точно управлять стилями через каскад CSS.


Переопределение стандартных стилей

Базовая стилизация Leaflet находится в файле leaflet.css. Для изменения внешнего вида контролов используется переопределение этих правил.

Пример изменения внешнего вида кнопок масштаба:

.leaflet-control-zoom a {
    background-color: #1e1e1e;
    color: #ffffff;
    border-bottom: 1px solid #333;
    width: 34px;
    height: 34px;
    line-height: 34px;
    text-align: center;
}

.leaflet-control-zoom a:hover {
    background-color: #333;
}

Ключевая особенность заключается в том, что Leaflet не инкапсулирует стили, поэтому любое правило может быть переопределено через более специфичный селектор.


Контроль визуальной иерархии

Контролы часто требуют адаптации под дизайн интерфейса приложения. Основные точки влияния:

  • фон контейнера (leaflet-control)
  • радиус скругления (border-radius)
  • тени (box-shadow)
  • отступы между кнопками
  • размеры интерактивных элементов

Пример унификации всех контролов под тёмную тему:

.leaflet-control {
    background: #121212;
    border: 1px solid #2a2a2a;
    border-radius: 8px;
    box-shadow: 0 2px 10px rgba(0,0,0,0.4);
}

.leaflet-control a,
.leaflet-control button {
    color: #e0e0e0;
}

Стилизация контролов слоёв

Контрол слоёв (L.control.layers) имеет более сложную DOM-структуру. Он включает список чекбоксов и радиокнопок, что требует отдельной стилизации.

Основные классы:

  • leaflet-control-layers-toggle
  • leaflet-control-layers-list
  • leaflet-control-layers-selector

Пример кастомизации панели:

.leaflet-control-layers {
    background: #1a1a1a;
    color: #fff;
    padding: 10px;
}

.leaflet-control-layers-list label {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
}

Часто применяется скрытие стандартного переключателя и замена его кастомными элементами через псевдоэлементы.


Полное отключение стандартного оформления

Иногда требуется полностью убрать дефолтный стиль Leaflet для интеграции в дизайн-систему.

Минимальный сброс:

.leaflet-control {
    all: unset;
}

После этого необходимо вручную восстановить базовые свойства:

.leaflet-control {
    display: block;
    background: transparent;
    position: relative;
}

Такой подход используется в интерфейсах, где Leaflet выступает как визуальный слой внутри сложного UI.


Кастомные контролы и их стилизация

Создание собственного контрола выполняется через расширение L.Control. Визуальная часть полностью контролируется разработчиком.

L.Control.CustomButton = L.Control.extend({
    onAdd: function(map) {
        const container = L.DomUtil.create('div', 'leaflet-control custom-control');

        const button = L.DomUtil.create('button', '', container);
        button.innerHTML = '⛶';

        L.DomEvent.on(button, 'click', function () {
            map.setView([0, 0], 2);
        });

        return container;
    }
});

L.control.customButton = function(opts) {
    return new L.Control.CustomButton(opts);
};

L.control.customButton({ position: 'topright' }).addTo(map);

CSS для такого контрола:

.custom-control {
    background: #202020;
    border-radius: 6px;
    padding: 6px;
}

.custom-control button {
    background: none;
    border: none;
    color: white;
    cursor: pointer;
    font-size: 16px;
}

Управление состояниями hover и active

Контролы в Leaflet не имеют встроенной системы состояний, поэтому вся интерактивность реализуется через CSS:

.leaflet-control a:active {
    transform: scale(0.95);
}

.leaflet-control a:hover {
    filter: brightness(1.2);
}

Для более сложных эффектов используется комбинация классов, добавляемых через Jav * aScript:

button.classList.add('is-active');
.custom-control .is-active {
    background: #ffcc00;
    color: #000;
}

Перестановка контролов и управление позиционированием

Каждый контрол добавляется в определённую позицию, что влияет на его визуальное взаимодействие с другими элементами интерфейса.

L.control.zoom({
    position: 'bottomright'
}).addTo(map);

CSS-структура позволяет дополнительно модифицировать отступы между группами:

.leaflet-bottom.leaflet-right .leaflet-control {
    margin-bottom: 12px;
    margin-right: 12px;
}

Адаптация под разные разрешения

Контролы требуют корректировки под мобильные устройства. Основной подход — медиазапросы:

@media (max-width: 600px) {
    .leaflet-control a {
        width: 40px;
        height: 40px;
        line-height: 40px;
    }

    .leaflet-control-layers {
        font-size: 14px;
    }
}

Дополнительно применяется увеличение зоны нажатия без изменения визуального размера:

.leaflet-control a {
    padding: 6px;
}

Интеграция с дизайн-системами

При интеграции Leaflet в UI-фреймворки (например, на основе BEM или utility-first подходов) контролы приводятся к единому стилевому стандарту:

.leaflet-control {
    font-family: var(--ui-font);
    border-radius: var(--radius-md);
    background: var(--control-bg);
    color: var(--text-primary);
}

Такой подход позволяет синхронизировать карту с остальными компонентами интерфейса без конфликтов каскада.


Работа с атрибуцией

Контрол атрибуции имеет фиксированную структуру, но его внешний вид также полностью изменяем:

.leaflet-control-attribution {
    background: rgba(0,0,0,0.6);
    color: #aaa;
    font-size: 11px;
    padding: 4px 8px;
}

Часто применяется скрытие отдельных элементов атрибуции через CSS:

.leaflet-control-attribution a {
    display: none;
}

Изоляция стилей и предотвращение конфликтов

При использовании сторонних библиотек часто возникают конфликты CSS. Решение — повышение специфичности:

.map-container .leaflet-control {
    border: none;
}

Или использование префиксированных контейнеров:

#map .leaflet-control {
    font-size: 12px;
}

Такой подход снижает риск переопределения глобальными стилями приложения.


Анимация контролов

Leaflet не включает анимации для UI-элементов, поэтому они добавляются вручную:

.leaflet-control {
    transition: all 0.2s ease;
}

.leaflet-control:hover {
    transform: translateY(-1px);
}

Анимации применяются осторожно, поскольку контролы часто используются в критических элементах управления картой и не должны отвлекать от взаимодействия с картой.