Максимальная ширина

В Mapbox GL JS визуализация карты полностью привязана к DOM-элементу, переданному в параметр container. Именно размеры этого контейнера определяют фактическую ширину и высоту отрисовываемого WebGL-канваса. Библиотека не управляет шириной самостоятельно и не накладывает собственных ограничений, поэтому все вопросы «максимальной ширины» решаются на уровне верстки и обновления размеров карты.

const map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/streets-v12',
  center: [0, 0],
  zoom: 2
});

Если контейнер не имеет явно заданной ширины, он будет подстраиваться под поведение блочной модели HTML, что часто приводит к неожиданным результатам при использовании гибких макетов.


CSS как основной механизм ограничения ширины

Ограничение максимальной ширины карты задаётся исключительно через CSS. Наиболее распространённый подход — использование свойства max-width, которое фиксирует верхнюю границу расширения контейнера.

.map-wrapper {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
}

#map {
  width: 100%;
  height: 500px;
}

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


Поведение Mapbox GL JS при изменении размеров

Библиотека не отслеживает изменения размеров DOM-элемента автоматически. Любое изменение ширины контейнера требует явного вызова метода:

map.resize();

Этот вызов пересчитывает viewport WebGL и синхронизирует внутренние координаты с текущими размерами canvas. Без него карта может отображаться некорректно: растянуто, обрезано или с пустыми областями.


Адаптивная ширина и resize-события

При работе с адаптивной версткой изменение ширины контейнера происходит постоянно: при ресайзе окна, смене ориентации экрана, раскрытии боковых панелей.

Типичная схема обработки:

window.addEventListener('resize', () => {
  map.resize();
});

Однако более точный подход использует ResizeObserver, который реагирует именно на изменение размеров контейнера, а не окна браузера:

const observer = new ResizeObserver(() => {
  map.resize();
});

observer.observe(document.getElementById('map'));

Это особенно важно при сложных интерфейсах, где ширина карты зависит от соседних элементов.


Максимальная ширина в flex и grid-раскладках

В современных интерфейсах карта часто является частью сложной компоновки: sidebar + content area + map viewport. В таких случаях максимальная ширина задаётся не напрямую карте, а её родительскому контейнеру.

Flexbox

.layout {
  display: flex;
}

.sidebar {
  width: 320px;
}

.map-container {
  flex: 1;
  max-width: 900px;
}

Здесь карта автоматически ограничивается доступным пространством flex-элемента, а max-width предотвращает чрезмерное расширение.

Grid Layout

.layout {
  display: grid;
  grid-template-columns: 300px 1fr;
}

.map-container {
  max-width: 1000px;
}

Grid-структуры часто более предсказуемы, так как фиксируют колонки, снижая необходимость дополнительных ограничений.


Центрирование карты при ограниченной ширине

При использовании max-width часто возникает задача центрирования карты в пределах доступного пространства.

.map-wrapper {
  max-width: 1200px;
  margin: 0 auto;
}

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


Влияние максимальной ширины на WebGL отрисовку

Ширина контейнера напрямую влияет на:

  • количество пикселей в WebGL canvas
  • нагрузку на GPU при рендеринге тайлов
  • частоту перерисовки при изменении viewport
  • плотность пикселей при devicePixelRatio

При увеличении максимальной ширины карта начинает потреблять больше ресурсов, особенно на высоких разрешениях, где canvas масштабируется с учётом DPR.


Ограничение ширины в сложных интерфейсах

В интерфейсах с панелями управления карта часто должна оставаться в пределах динамически изменяемого контейнера.

.sidebar-open .map-container {
  max-width: calc(100vw - 320px);
}

Здесь максимальная ширина зависит от состояния интерфейса, что позволяет карте автоматически подстраиваться под открытие/закрытие боковой панели.


Изменение ширины через JavaScript-логику

Иногда максимальная ширина задаётся не только CSS, но и логикой приложения:

function setMapWidth(state) {
  const mapContainer = document.getElementById('map');

  if (state === 'compact') {
    mapContainer.style.maxWidth = '600px';
  } else {
    mapContainer.style.maxWidth = '1200px';
  }

  map.resize();
}

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


Синхронизация ширины с анимациями интерфейса

При анимации боковых панелей изменение ширины происходит постепенно, что требует синхронного обновления карты:

const sidebar = document.querySelector('.sidebar');

sidebar.addEventListener('transitionend', () => {
  map.resize();
});

Без этой синхронизации карта может «дёргаться» или оставлять артефакты при промежуточных состояниях ширины.


Ограничение ширины через viewport-единицы

Современный подход включает использование vw для динамического контроля максимальной ширины:

.map-container {
  max-width: 80vw;
}

Это позволяет карте масштабироваться относительно окна браузера, сохраняя пропорциональность интерфейса на разных устройствах.


Типичные проблемы при неверной настройке ширины

При отсутствии корректного управления максимальной шириной возникают характерные эффекты:

  • смещение центра карты при изменении размера контейнера
  • появление пустых серых областей по краям canvas
  • некорректное масштабирование тайлов
  • визуальные разрывы при анимациях интерфейса

Все эти проблемы не связаны с рендерингом карты напрямую, а являются следствием несоответствия размеров контейнера и внутреннего состояния WebGL viewport.


Ограничение ширины в SPA-приложениях

В одностраничных приложениях ширина карты часто зависит от маршрутизации и состояния интерфейса:

router.onChange((route) => {
  const mapContainer = document.getElementById('map');

  mapContainer.style.maxWidth =
    route === 'fullscreen' ? '100vw' : '900px';

  map.resize();
});

Такая динамика требует строгой синхронизации состояния DOM и состояния карты, поскольку Mapbox GL JS не имеет встроенного наблюдения за layout-состоянием приложения.


Комбинирование максимальной ширины и минимальной ширины

Для стабильного поведения часто задаются обе границы:

.map-container {
  min-width: 320px;
  max-width: 1200px;
  width: 100%;
}

Это предотвращает как чрезмерное сжатие на мобильных устройствах, так и чрезмерное расширение на больших экранах, сохраняя предсказуемость интерфейса и корректную работу map.resize() при любых изменениях размеров.