Автоматическое позиционирование

Автоматическое позиционирование календаря в Pikaday строится вокруг вычисления геометрии связки «поле ввода — всплывающий календарь — viewport» и динамической корректировки координат всплывающего элемента в зависимости от доступного пространства. Основная цель механизма заключается в том, чтобы календарь всегда оставался видимым и не выходил за границы окна браузера или заданного контейнера.


Базовая модель размещения календаря

При активации календаря Pikaday создаёт DOM-элемент календаря и размещает его либо в document.body, либо в пользовательском контейнере, если он задан через параметр конфигурации. Далее выполняется первичное позиционирование относительно связанного input-элемента.

Ключевая логика основана на следующих этапах:

  • получение координат поля ввода через getBoundingClientRect()
  • вычисление размеров календаря после рендера
  • определение доступного пространства сверху и снизу
  • выбор оптимального направления отображения
  • установка top и left в стиле календаря

По умолчанию календарь пытается появиться под полем ввода, выравниваясь по левому краю.


Привязка к полю ввода и параметр bound

Параметр bound определяет, будет ли календарь «прикреплён» к полю ввода с автоматическим управлением позиционированием.

При bound: true включается полноценная система адаптивного размещения:

  • календарь остаётся в пределах viewport
  • учитываются скролл и изменение размеров окна
  • активируется пересчёт позиции при открытии и взаимодействии

При bound: false календарь ведёт себя как свободный всплывающий элемент, и ответственность за позиционирование частично перекладывается на разработчика.


Алгоритм выбора вертикального положения

Вертикальное позиционирование определяется сравнением доступного пространства:

  • пространство снизу от input до нижней границы окна
  • пространство сверху от input до верхней границы окна

Если пространства снизу достаточно для полной высоты календаря, он размещается под полем ввода. Если нет — выполняется проверка верхней области.

Приоритет логики:

  1. размещение снизу (default)
  2. размещение сверху при нехватке места снизу
  3. коррекция при частичном выходе за границы

В случае ограниченного пространства с обеих сторон применяется компромиссное позиционирование с сдвигом внутри доступной области viewport.


Горизонтальное выравнивание и корректировка смещения

Горизонтальная позиция базируется на left координате input-элемента. Однако при вычислении учитываются следующие ограничения:

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

Если календарь выходит за правую границу viewport, применяется сдвиг влево:

  • left = viewportWidth - calendarWidth - margin

Если происходит выход за левую границу, значение принудительно устанавливается в 0 или минимальный отступ.

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


Роль метода reposition и динамическое обновление координат

Pikaday пересчитывает позицию календаря не только при открытии, но и при изменении окружения. Внутренний механизм включает вызов логики reposition при следующих событиях:

  • прокрутка страницы
  • изменение размера окна
  • изменение положения input в DOM (в некоторых сценариях)
  • повторное открытие календаря

Пересчёт координат выполняется на основе актуального getBoundingClientRect(), что позволяет учитывать трансформации layout-а, включая sticky- и fixed-элементы.


Влияние контейнера (container) на систему координат

Параметр container меняет систему отсчёта для позиционирования календаря.

При использовании container:

  • календарь позиционируется относительно заданного DOM-узла
  • координаты вычисляются в пределах контейнера, а не viewport
  • учитываются overflow-ограничения контейнера
  • появляется зависимость от CSS position родительских элементов

Если контейнер имеет overflow: hidden, возможны ситуации частичного обрезания календаря, что влияет на стратегию позиционирования.


Учёт скролла страницы

Pikaday корректирует позицию с учётом текущего scroll offset. Поскольку getBoundingClientRect() возвращает координаты относительно viewport, дополнительно учитываются:

  • window.scrollY
  • window.scrollX

Это позволяет преобразовать координаты в абсолютные значения при использовании position: absolute.

При использовании position: fixed корректировка scroll может не применяться, так как координаты уже привязаны к viewport.


Поведение при переполнении viewport

Когда календарь не помещается полностью в доступное пространство, применяется стратегия адаптивного смещения:

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

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


Обработка событий открытия

При открытии календаря происходит последовательность операций:

  • рендер DOM календаря (если он ещё не создан)
  • измерение размеров элемента после вставки в DOM
  • вычисление позиции относительно input
  • применение стилей top и left
  • проверка границ viewport
  • возможная корректировка позиции

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


Синхронизация с CSS и трансформациями

Автоматическое позиционирование может искажаться при наличии CSS трансформаций у родительских элементов:

  • transform: translate(...)
  • transform: scale(...)
  • transform: rotate(...)

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


Поведение при фиксированных и абсолютных контекстах

Различие между position: absolute и position: fixed влияет на модель расчёта координат:

  • absolute использует документную систему координат
  • fixed привязан к viewport

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


Ограничения автоматического позиционирования

Несмотря на адаптивность, механизм имеет ряд ограничений:

  • невозможность идеальной адаптации в сильно вложенных flex/grid контейнерах с overflow
  • возможные ошибки при нестандартных transform-комбинациях
  • зависимость от точности размеров, полученных после рендера
  • отсутствие полноценного collision detection с произвольными DOM-элементами

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


Взаимодействие с пользовательскими стилями

Стилизация календаря напрямую влияет на позиционирование, особенно при изменении:

  • ширины календаря
  • высоты заголовка и сетки дней
  • padding и border-box модели

Изменение этих параметров может привести к изменению логики выбора стороны отображения, так как алгоритм опирается на фактические размеры элемента после рендеринга.