Автоматическое позиционирование календаря в Pikaday строится вокруг задачи корректного отображения всплывающего UI-элемента относительно input-поля с учётом границ viewport, прокрутки контейнеров и доступного пространства. Основная цель механизма — предотвратить обрезание календаря за пределами экрана и обеспечить предсказуемое поведение при изменении размеров окна или скролле страницы.
Pikaday создаёт отдельный DOM-элемент календаря и привязывает его к
полю ввода. По умолчанию используется абсолютное позиционирование
относительно документа или указанного контейнера. При открытии календаря
вычисляются координаты input-элемента через
getBoundingClientRect(), после чего рассчитывается
начальная точка размещения.
Ключевые параметры, влияющие на позицию:
После первичного вычисления выполняется проверка на переполнение границ экрана.
При стандартной конфигурации Pikaday пытается отобразить календарь под input-полем. Если доступного пространства снизу недостаточно, выполняется переключение вверх.
Логика упрощённо выглядит так:
Аналогичная проверка выполняется по горизонтали, если календарь выходит за правый край экрана.
Особое внимание уделяется случаям, когда input расположен близко к краям экрана — тогда применяется комбинированная корректировка по обеим осям.
Каждое открытие календаря инициирует пересчёт координат. Это важно, поскольку DOM может измениться между инициализацией и открытием:
Pikaday вызывает внутреннюю процедуру позиционирования
непосредственно в момент onOpen, гарантируя актуальность
расчётов.
Важный аспект: позиция не кэшируется, а вычисляется заново при каждом открытии.
При размещении календаря внутри scroll-контейнера возникает дополнительная сложность: координаты input становятся относительными к текущему состоянию прокрутки.
Для корректной работы учитываются:
scrollTop и scrollLeft родительских
элементовposition: fixedЕсли календарь привязан к document.body, он ведёт себя
как overlay-элемент и реагирует на глобальные координаты viewport. При
привязке к кастомному контейнеру расчёт смещается в локальную систему
координат.
Pikaday не ограничивается статическим вычислением позиции при открытии. В типичных конфигурациях реализуется пересчёт при изменении размеров окна браузера.
При событии resize выполняется:
Это предотвращает ситуацию, когда календарь «уезжает» за пределы экрана после изменения ориентации устройства или изменения размеров окна.
Flip-логика является основным элементом автоматического позиционирования. Она отвечает за переключение календаря между верхним и нижним отображением.
Условно поведение можно описать так:
Дополнительно учитывается ширина календаря, чтобы избежать выхода за правый край экрана.
При автоматическом перепозиционировании Pikaday использует CSS-классы, отражающие текущее положение календаря. Это позволяет стилизовать разные сценарии отображения.
Часто используются состояния:
CSS-классы позволяют компенсировать визуальные проблемы, возникающие при изменении позиции, например изменение стрелки-указателя календаря.
Параметр container влияет на систему координат, в
которой выполняется расчёт позиции. При его использовании календарь:
Это особенно важно в модальных окнах и компонентах с ограниченной областью видимости.
В таких случаях автоматическое позиционирование становится более сложным, так как границы ограничены не viewport, а внутренним контейнером.
Размер календаря Pikaday зависит от:
При изменении месяца высота календаря может изменяться, что требует повторного пересчёта позиционирования в некоторых сценариях. В таких случаях вызывается внутренняя функция перерасчёта координат, аналогичная первичному алгоритму открытия.
На мобильных устройствах автоматическое позиционирование сталкивается с дополнительными ограничениями:
В этих условиях Pikaday ориентируется на актуальные размеры
window.innerHeight, а не на статические значения viewport,
что позволяет адаптировать позицию календаря под реальные доступные
границы.
Автоматическое позиционирование может давать некорректные результаты при наличии CSS-свойств:
transform у родительских элементовoverflow: hidden на контейнерахposition: relative с нестандартными контекстами
наложенияВ таких случаях координатная система может смещаться, и Pikaday компенсирует это через пересчёт offset-значений и переход к body-контексту.
Некоторые сценарии требуют ручного вызова пересчёта позиции. Для
этого используется метод adjustPosition() (или аналогичные
внутренние механизмы библиотеки в зависимости от версии).
Он выполняет:
Это полезно при динамическом изменении layout, например при раскрытии сайдбаров или модальных окон поверх календаря.
В случаях, когда календарь отображается с анимацией (fade/scale), позиционирование должно происходить до начала анимации. Иначе возможны визуальные скачки.
Поэтому порядок операций обычно следующий:
Нарушение этого порядка приводит к эффекту «перепрыгивания» календаря при открытии.
Если одновременно выполняется несколько условий переполнения (например, нет места ни сверху, ни снизу), Pikaday выбирает стратегию минимального смещения:
В крайних случаях календарь может быть частично обрезан, если невозможно найти полностью свободную область отображения.